home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Utilities / vim-5.1 / src / option.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-05  |  109.6 KB  |  4,393 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /*
  10.  * Code to handle user-settable options. This is all pretty much table-
  11.  * driven. Checklist for adding a new option:
  12.  * - Put it in the options array below (copy an existing entry).
  13.  * - For a global option: Add a variable for it in option.h.
  14.  * - For a buffer or window local option:
  15.  *   - Add a PV_XX entry to the enum below.
  16.  *   - Add a variable to the window or buffer struct in structs.h.
  17.  *   - For a window option, add some code to win_copy_options().
  18.  *   - For a buffer option, add some code to buf_copy_options().
  19.  *   - For a buffer string option, add code to check_buf_options().
  20.  * - If it's a numeric option, add any necessary bounds checks to do_set().
  21.  * - If it's a list of flags, add some code in do_set(), search for WW_ALL.
  22.  * - When adding an option with expansion (P_EXPAND), but with a different
  23.  *   default for Vi and Vim (no P_VI_DEF), add some code at VIMEXP.
  24.  * - Add documentation!  One line in doc/help.txt, full description in
  25.  *   options.txt, and any other related places.
  26.  */
  27.  
  28. #include "vim.h"
  29.  
  30. struct vimoption
  31. {
  32.     char    *fullname;    /* full option name */
  33.     char    *shortname;    /* permissible abbreviation */
  34.     short    flags;        /* see below */
  35.     char_u    *var;        /* pointer to variable */
  36.     char_u    *def_val[2];    /* default values for variable (vi and vim) */
  37. };
  38.  
  39. #define VI_DEFAULT  0        /* def_val[VI_DEFAULT] is Vi default value */
  40. #define VIM_DEFAULT 1        /* def_val[VIM_DEFAULT] is Vim default value */
  41.  
  42. /*
  43.  * Flags
  44.  *
  45.  * Note: P_EXPAND and P_IND can never be used at the same time.
  46.  * Note: P_IND cannot be used for a terminal option.
  47.  */
  48. #define P_BOOL        0x01    /* the option is boolean */
  49. #define P_NUM        0x02    /* the option is numeric */
  50. #define P_STRING    0x04    /* the option is a string */
  51. #define P_ALLOCED    0x08    /* the string option is in allocated memory,
  52.                     must use vim_free() when assigning new
  53.                     value. Not set if default is the same. */
  54. #define P_EXPAND    0x10    /* environment expansion */
  55. #define P_IND        0x20    /* indirect, is in curwin or curbuf */
  56. #define P_NODEFAULT    0x40    /* has no default value */
  57. #define P_DEF_ALLOCED    0x80    /* default value is in allocated memory, must
  58.                     use vim_free() when assigning new value */
  59. #define P_WAS_SET    0x100    /* option has been set/reset */
  60. #define P_NO_MKRC    0x200    /* don't include in :mkvimrc output */
  61. #define P_VI_DEF    0x400    /* Use Vi default for Vim */
  62. #define P_VIM        0x800    /* Vim option, reset when 'cp' set */
  63.  
  64. #define P_RSTAT        0x1000    /* when changed, redraw status lines */
  65. #define P_RBUF        0x2000    /* when changed, redraw current buffer */
  66. #define P_RALL        0x4000    /* when changed, redraw all */
  67.  
  68. /*
  69.  * The options that are in curwin or curbuf have P_IND set and a var field
  70.  * that contains one of the enum values below.
  71.  */
  72. enum indirect_options
  73. {
  74.     PV_AI = 1,
  75.     PV_BIN,
  76.     PV_CIN,
  77.     PV_CINK,
  78.     PV_CINO,
  79.     PV_CINW,
  80.     PV_COM,
  81.     PV_CPT,
  82.     PV_EOL,
  83.     PV_ET,
  84.     PV_FF,
  85.     PV_FO,
  86.     PV_INF,
  87.     PV_ISK,
  88.     PV_LBR,
  89.     PV_LISP,
  90.     PV_LIST,
  91.     PV_ML,
  92.     PV_MOD,
  93.     PV_NF,
  94.     PV_NU,
  95.     PV_RL,
  96.     PV_RO,
  97.     PV_SCROLL,
  98.     PV_SI,
  99.     PV_SN,
  100.     PV_STS,
  101.     PV_SW,
  102.     PV_TS,
  103.     PV_TW,
  104.     PV_TX,
  105.     PV_WM,
  106.     PV_WRAP
  107. };
  108.  
  109. /*
  110.  * options[] is initialized here.
  111.  * The order of the options MUST be alphabetic for ":set all" and findoption().
  112.  * All option names MUST start with a lowercase letter (for findoption()).
  113.  * Exception: "t_" options are at the end.
  114.  * The options with a NULL variable are 'hidden': a set command for them is
  115.  * ignored and they are not printed.
  116.  */
  117. static struct vimoption options[] =
  118. {
  119. #ifdef RIGHTLEFT
  120.     {"aleph",        "al",   P_NUM|P_VI_DEF,
  121.                 (char_u *)&p_aleph,
  122.                 {
  123. # if (defined(MSDOS) || defined(WIN32) || defined(OS2)) && !defined(USE_GUI_WIN32)
  124.                 (char_u *)128L,
  125. # else
  126.                 (char_u *)224L,
  127. # endif
  128.                         (char_u *)0L}},
  129. #endif
  130. #ifdef FKMAP
  131.     {"altkeymap",   "akm",  P_BOOL|P_VI_DEF,
  132.                 (char_u *)&p_altkeymap,
  133.                 {(char_u *)FALSE, (char_u *)0L}},
  134. #endif
  135.     {"autoindent",  "ai",   P_BOOL|P_IND|P_VI_DEF,
  136.                 (char_u *)PV_AI,
  137.                 {(char_u *)FALSE, (char_u *)0L}},
  138.     {"autoprint",   "ap",   P_BOOL|P_VI_DEF,
  139.                 (char_u *)NULL,
  140.                 {(char_u *)FALSE, (char_u *)0L}},
  141.     {"autowrite",   "aw",   P_BOOL|P_VI_DEF,
  142.                 (char_u *)&p_aw,
  143.                 {(char_u *)FALSE, (char_u *)0L}},
  144.     {"background",  "bg",   P_STRING|P_VI_DEF|P_RALL,
  145.                 (char_u *)&p_bg,
  146.                 {
  147. #if (defined(MSDOS) || defined(OS2) || defined(WIN32)) && !defined(USE_GUI)
  148.                 (char_u *)"dark",
  149. #else
  150.                 (char_u *)"light",
  151. #endif
  152.                         (char_u *)0L}},
  153.     {"backspace",   "bs",   P_NUM|P_VI_DEF|P_VIM,
  154.                 (char_u *)&p_bs,
  155.                 {(char_u *)0L, (char_u *)0L}},
  156.     {"backup",        "bk",   P_BOOL|P_VI_DEF|P_VIM,
  157.                 (char_u *)&p_bk,
  158.                 {(char_u *)FALSE, (char_u *)0L}},
  159.     {"backupdir",   "bdir", P_STRING|P_EXPAND|P_VI_DEF,
  160.                 (char_u *)&p_bdir,
  161.                 {(char_u *)DEF_BDIR, (char_u *)0L}},
  162.     {"backupext",   "bex",  P_STRING|P_VI_DEF,
  163.                 (char_u *)&p_bex,
  164.                 {
  165. #ifdef VMS
  166.                 (char_u *)"_",
  167. #else
  168.                 (char_u *)"~",
  169. #endif
  170.                         (char_u *)0L}},
  171.     {"beautify",    "bf",   P_BOOL|P_VI_DEF,
  172.                 (char_u *)NULL,
  173.                 {(char_u *)FALSE, (char_u *)0L}},
  174.     {"binary",        "bin",  P_BOOL|P_IND|P_VI_DEF|P_RSTAT,
  175.                 (char_u *)PV_BIN,
  176.                 {(char_u *)FALSE, (char_u *)0L}},
  177.     {"bioskey",        "biosk",P_BOOL|P_VI_DEF,
  178. #ifdef MSDOS
  179.                 (char_u *)&p_biosk,
  180. #else
  181.                 (char_u *)NULL,
  182. #endif
  183.                 {(char_u *)TRUE, (char_u *)0L}},
  184.     {"breakat",        "brk",  P_STRING|P_VI_DEF|P_RALL,
  185.                 (char_u *)&p_breakat,
  186.                 {(char_u *)" \t!@*-+_;:,./?", (char_u *)0L}},
  187. #ifdef CINDENT
  188.     {"cindent",        "cin",  P_BOOL|P_IND|P_VI_DEF|P_VIM,
  189.                 (char_u *)PV_CIN,
  190.                 {(char_u *)FALSE, (char_u *)0L}},
  191.     {"cinkeys",        "cink", P_STRING|P_IND|P_ALLOCED|P_VI_DEF,
  192.                 (char_u *)PV_CINK,
  193.                 {(char_u *)"0{,0},:,0#,!^F,o,O,e", (char_u *)0L}},
  194.     {"cinoptions",  "cino", P_STRING|P_IND|P_ALLOCED|P_VI_DEF,
  195.                 (char_u *)PV_CINO,
  196.                 {(char_u *)"", (char_u *)0L}},
  197. #endif /* CINDENT */
  198. #if defined(SMARTINDENT) || defined(CINDENT)
  199.     {"cinwords",    "cinw", P_STRING|P_IND|P_ALLOCED|P_VI_DEF,
  200.                 (char_u *)PV_CINW,
  201.                 {(char_u *)"if,else,while,do,for,switch",
  202.                 (char_u *)0L}},
  203. #endif
  204.     {"cmdheight",   "ch",   P_NUM|P_VI_DEF|P_RALL,
  205.                 (char_u *)&p_ch,
  206.                 {(char_u *)1L, (char_u *)0L}},
  207.     {"columns",        "co",   P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL,
  208.                 (char_u *)&Columns,
  209.                 {(char_u *)80L, (char_u *)0L}},
  210.     {"comments",    "com",  P_STRING|P_IND|P_ALLOCED|P_VI_DEF,
  211.                 (char_u *)PV_COM,
  212.                 {(char_u *)"sr:/*,mb:*,el:*/,://,b:#,:%,:XCOMM,n:>,fb:-",
  213.                 (char_u *)0L}},
  214.     {"compatible",  "cp",   P_BOOL|P_RALL,
  215.                 (char_u *)&p_cp,
  216.                 {(char_u *)TRUE, (char_u *)FALSE}},
  217. #ifdef INSERT_EXPAND
  218.     {"complete",    "cpt",  P_STRING|P_IND|P_ALLOCED|P_VI_DEF,
  219.                 (char_u *)PV_CPT,
  220.                 {(char_u *)".,b", (char_u *)0L}},
  221. #endif
  222.     {"cpoptions",   "cpo",  P_STRING|P_VIM|P_RALL,
  223.                 (char_u *)&p_cpo,
  224.                 {(char_u *)CPO_ALL, (char_u *)CPO_DEFAULT}},
  225.     {"define",        "def",  P_STRING|P_VI_DEF,
  226.                 (char_u *)&p_def,
  227.                 {(char_u *)"^#\\s*define", (char_u *)0L}},
  228.     {"dictionary",  "dict", P_STRING|P_EXPAND|P_VI_DEF,
  229.                 (char_u *)&p_dict,
  230.                 {(char_u *)"", (char_u *)0L}},
  231.     {"digraph",        "dg",   P_BOOL|P_VI_DEF|P_VIM,
  232. #ifdef DIGRAPHS
  233.                 (char_u *)&p_dg,
  234. #else
  235.                 (char_u *)NULL,
  236. #endif
  237.                 {(char_u *)FALSE, (char_u *)0L}},
  238.     {"directory",   "dir",  P_STRING|P_EXPAND|P_VI_DEF,
  239.                 (char_u *)&p_dir,
  240.                 {(char_u *)DEF_DIR, (char_u *)0L}},
  241.     {"edcompatible","ed",   P_BOOL|P_VI_DEF,
  242.                 (char_u *)&p_ed,
  243.                 {(char_u *)FALSE, (char_u *)0L}},
  244.     {"endofline",   "eol",  P_BOOL|P_IND|P_NO_MKRC|P_VI_DEF|P_RSTAT,
  245.                 (char_u *)PV_EOL,
  246.                 {(char_u *)TRUE, (char_u *)0L}},
  247.     {"equalalways", "ea",   P_BOOL|P_VI_DEF|P_RALL,
  248.                 (char_u *)&p_ea,
  249.                 {(char_u *)TRUE, (char_u *)0L}},
  250.     {"equalprg",    "ep",   P_STRING|P_EXPAND|P_VI_DEF,
  251.                 (char_u *)&p_ep,
  252.                 {(char_u *)"", (char_u *)0L}},
  253.     {"errorbells",  "eb",   P_BOOL|P_VI_DEF,
  254.                 (char_u *)&p_eb,
  255.                 {(char_u *)FALSE, (char_u *)0L}},
  256.     {"errorfile",   "ef",   P_STRING|P_EXPAND|P_VI_DEF,
  257.                 (char_u *)&p_ef,
  258.                 {(char_u *)ERRORFILE, (char_u *)0L}},
  259.     {"errorformat", "efm",  P_STRING|P_VI_DEF,
  260.                 (char_u *)&p_efm,
  261.                 {(char_u *)EFM_DFLT, (char_u *)0L}},
  262.     {"esckeys",        "ek",   P_BOOL|P_VIM,
  263.                 (char_u *)&p_ek,
  264.                 {(char_u *)FALSE, (char_u *)TRUE}},
  265.     {"eventignore", "ei",   P_STRING|P_VI_DEF,
  266. #ifdef AUTOCMD
  267.                 (char_u *)&p_ei,
  268. #else
  269.                 (char_u *)NULL,
  270. #endif
  271.                 {(char_u *)"", (char_u *)0L}},
  272.     {"expandtab",   "et",   P_BOOL|P_IND|P_VI_DEF|P_VIM,
  273.                 (char_u *)PV_ET,
  274.                 {(char_u *)FALSE, (char_u *)0L}},
  275.     {"exrc",        "ex",   P_BOOL|P_VI_DEF,
  276.                 (char_u *)&p_exrc,
  277.                 {(char_u *)FALSE, (char_u *)0L}},
  278.     {"fileformat",  "ff",   P_STRING|P_IND|P_ALLOCED|P_VI_DEF|P_RSTAT,
  279.                 (char_u *)PV_FF,
  280.                 {(char_u *)FF_DFLT, (char_u *)0L}},
  281.     {"fileformats", "ffs",  P_STRING|P_VIM,
  282.                 (char_u *)&p_ffs,
  283.                 {(char_u *)FFS_VI, (char_u *)FFS_DFLT}},
  284. #ifdef FKMAP
  285.     {"fkmap",        "fk",   P_BOOL|P_VI_DEF,
  286.                 (char_u *)&p_fkmap,
  287.                 {(char_u *)FALSE, (char_u *)0L}},
  288. #endif
  289.     {"flash",        "fl",   P_BOOL|P_VI_DEF,
  290.                 (char_u *)NULL,
  291.                 {(char_u *)FALSE, (char_u *)0L}},
  292.     {"formatoptions","fo",  P_STRING|P_IND|P_ALLOCED|P_VIM,
  293.                 (char_u *)PV_FO,
  294.                 {(char_u *)FO_DFLT_VI, (char_u *)FO_DFLT}},
  295.     {"formatprg",   "fp",   P_STRING|P_EXPAND|P_VI_DEF,
  296.                 (char_u *)&p_fp,
  297.                 {(char_u *)"", (char_u *)0L}},
  298.     {"gdefault",    "gd",   P_BOOL|P_VI_DEF|P_VIM,
  299.                 (char_u *)&p_gd,
  300.                 {(char_u *)FALSE, (char_u *)0L}},
  301.     {"graphic",        "gr",   P_BOOL|P_VI_DEF,
  302.                 (char_u *)NULL,
  303.                 {(char_u *)FALSE, (char_u *)0L}},
  304.     {"guicursor",    "gcr",  P_STRING|P_VI_DEF,
  305. #ifdef USE_GUI
  306.                 (char_u *)&p_guicursor,
  307.                 {(char_u *)"n-v-c:block-Cursor,o:hor50-Cursor,i-ci:ver25-Cursor,r-cr:hor20-Cursor,sm:block-Cursor-blinkwait175-blinkoff150-blinkon175",
  308.                     (char_u *)0L}
  309. #else
  310.                 (char_u *)NULL,
  311.                 {(char_u *)NULL, (char_u *)0L}
  312. #endif
  313.                     },
  314.     {"guifont",        "gfn",  P_STRING|P_VI_DEF|P_RALL,
  315. #ifdef USE_GUI
  316.                 (char_u *)&p_guifont,
  317.                 {(char_u *)"", (char_u *)0L}
  318. #else
  319.                 (char_u *)NULL,
  320.                 {(char_u *)NULL, (char_u *)0L}
  321. #endif
  322.                     },
  323.     {"guioptions",  "go",   P_STRING|P_VI_DEF|P_RALL,
  324. #if defined(USE_GUI) || defined(USE_CLIPBOARD)
  325.                 (char_u *)&p_guioptions,
  326. # ifdef UNIX
  327.                 {(char_u *)"agmr", (char_u *)0L}
  328. # else
  329.                 {(char_u *)"gmr", (char_u *)0L}
  330. # endif
  331. #else
  332.                 (char_u *)NULL,
  333.                 {(char_u *)NULL, (char_u *)0L}
  334. #endif
  335.                     },
  336. #if defined(USE_GUI)
  337.     {"guipty",        NULL,   P_BOOL|P_VI_DEF,
  338.                 (char_u *)&p_guipty,
  339.                 {(char_u *)TRUE, (char_u *)0L}},
  340. #endif
  341.     {"hardtabs",    "ht",   P_NUM|P_VI_DEF,
  342.                 (char_u *)NULL,
  343.                 {(char_u *)0L, (char_u *)0L}},
  344.     {"helpfile",    "hf",   P_STRING|P_EXPAND|P_VI_DEF,
  345.                 (char_u *)&p_hf,
  346.                 {(char_u *)VIM_HLP, (char_u *)0L}},
  347.     {"helpheight",  "hh",   P_NUM|P_VI_DEF,
  348.                 (char_u *)&p_hh,
  349.                 {(char_u *)20L, (char_u *)0L}},
  350.     {"hidden",        "hid",  P_BOOL|P_VI_DEF,
  351.                 (char_u *)&p_hid,
  352.                 {(char_u *)FALSE, (char_u *)0L}},
  353.     {"highlight",   "hl",   P_STRING|P_VI_DEF|P_RALL,
  354.                 (char_u *)&p_hl,
  355.                 {(char_u *)"8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,t:Title,v:Visual,w:WarningMsg",
  356.                 (char_u *)0L}},
  357.     {"hlsearch",    "hls",  P_BOOL|P_VI_DEF|P_VIM|P_RALL,
  358.                 (char_u *)&p_hls,
  359.                 {(char_u *)FALSE, (char_u *)0L}},
  360.     {"history",        "hi",   P_NUM|P_VIM,
  361.                 (char_u *)&p_hi,
  362.                 {(char_u *)0L, (char_u *)20L}},
  363. #ifdef RIGHTLEFT
  364.     {"hkmap",        "hk",   P_BOOL|P_VI_DEF|P_VIM,
  365.                 (char_u *)&p_hkmap,
  366.                 {(char_u *)FALSE, (char_u *)0L}},
  367.     {"hkmapp",        "hkp",  P_BOOL|P_VI_DEF|P_VIM,
  368.                 (char_u *)&p_hkmapp,
  369.                 {(char_u *)FALSE, (char_u *)0L}},
  370. #endif
  371.     {"icon",        NULL,   P_BOOL|P_VI_DEF,
  372.                 (char_u *)&p_icon,
  373.                 {(char_u *)FALSE, (char_u *)0L}},
  374.     {"iconstring",  NULL,   P_STRING|P_VI_DEF,
  375.                 (char_u *)&p_iconstring,
  376.                 {(char_u *)"", (char_u *)0L}},
  377.     {"ignorecase",  "ic",   P_BOOL|P_VI_DEF,
  378.                 (char_u *)&p_ic,
  379.                 {(char_u *)FALSE, (char_u *)0L}},
  380.     {"include",        "inc",  P_STRING|P_VI_DEF,
  381.                 (char_u *)&p_inc,
  382.                 {(char_u *)"^#\\s*include", (char_u *)0L}},
  383.     {"incsearch",   "is",   P_BOOL|P_VI_DEF|P_VIM,
  384.                 (char_u *)&p_is,
  385.                 {(char_u *)FALSE, (char_u *)0L}},
  386.     {"infercase",   "inf",  P_BOOL|P_IND|P_VI_DEF,
  387.                 (char_u *)PV_INF,
  388.                 {(char_u *)FALSE, (char_u *)0L}},
  389.     {"insertmode",  "im",   P_BOOL|P_VI_DEF|P_VIM,
  390.                 (char_u *)&p_im,
  391.                 {(char_u *)FALSE, (char_u *)0L}},
  392.     {"isfname",        "isf",  P_STRING|P_VI_DEF,
  393.                 (char_u *)&p_isf,
  394.                 {
  395. #ifdef BACKSLASH_IN_FILENAME
  396.                 (char_u *)"@,48-57,/,.,-,_,+,,,$,:,\\",
  397. #else
  398. # ifdef AMIGA
  399.                 (char_u *)"@,48-57,/,.,-,_,+,,,$,:",
  400. # else /* UNIX */
  401.                 (char_u *)"@,48-57,/,.,-,_,+,,,$,~",
  402. # endif
  403. #endif
  404.                 (char_u *)0L}},
  405.     {"isident",        "isi",  P_STRING|P_VI_DEF,
  406.                 (char_u *)&p_isi,
  407.                 {
  408. #if defined(MSDOS) || defined(WIN32) || defined(OS2)
  409.                 (char_u *)"@,48-57,_,128-167,224-235",
  410. #else
  411.                 (char_u *)"@,48-57,_,192-255",
  412. #endif
  413.                 (char_u *)0L}},
  414.     {"iskeyword",   "isk",  P_STRING|P_IND|P_ALLOCED|P_VIM,
  415.                 (char_u *)PV_ISK,
  416.                 {(char_u *)"@,48-57,_",
  417. # if defined(MSDOS) || defined(WIN32) || defined(OS2)
  418.                 (char_u *)"@,48-57,_,128-167,224-235"
  419. # else
  420.                 (char_u *)"@,48-57,_,192-255"
  421. # endif
  422.                 }},
  423.     {"isprint",        "isp",  P_STRING|P_VI_DEF|P_RALL,
  424.                 (char_u *)&p_isp,
  425.                 {
  426. #if defined(MSDOS) || defined(WIN32) || defined(OS2)
  427.                 (char_u *)"@,~-255",
  428. #else
  429.                 (char_u *)"@,161-255",
  430. #endif
  431.                 (char_u *)0L}},
  432.     {"joinspaces",  "js",   P_BOOL|P_VI_DEF|P_VIM,
  433.                 (char_u *)&p_js,
  434.                 {(char_u *)TRUE, (char_u *)0L}},
  435.     {"keywordprg",  "kp",   P_STRING|P_EXPAND|P_VI_DEF,
  436.                 (char_u *)&p_kp,
  437.                 {
  438. #if defined(MSDOS) || defined(WIN32)
  439.                 (char_u *)"",
  440. #else
  441. # if defined(OS2)
  442.                 (char_u *)"view /",
  443. # else
  444.                 (char_u *)"man",
  445. # endif
  446. #endif
  447.                 (char_u *)0L}},
  448.     {"langmap",     "lmap", P_STRING|P_VI_DEF,
  449. #ifdef HAVE_LANGMAP
  450.                 (char_u *)&p_langmap,
  451.                 {(char_u *)"",    /* unmatched } */
  452. #else
  453.                 (char_u *)NULL,
  454.                 {(char_u *)NULL,
  455. #endif
  456.                 (char_u *)0L}},
  457.     {"laststatus",  "ls",   P_NUM|P_VI_DEF|P_RALL,
  458.                 (char_u *)&p_ls,
  459.                 {(char_u *)1L, (char_u *)0L}},
  460.     {"lazyredraw",  "lz",   P_BOOL|P_VI_DEF,
  461.                 (char_u *)&p_lz,
  462.                 {(char_u *)FALSE, (char_u *)0L}},
  463.     {"linebreak",   "lbr",  P_BOOL|P_IND|P_VI_DEF|P_RBUF,
  464.                 (char_u *)PV_LBR,
  465.                 {(char_u *)FALSE, (char_u *)0L}},
  466.     {"lines",        NULL,   P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL,
  467.                 (char_u *)&Rows,
  468.                 {
  469. #if defined(MSDOS) || defined(WIN32) || defined(OS2)
  470.                 (char_u *)25L,
  471. #else
  472.                 (char_u *)24L,
  473. #endif
  474.                         (char_u *)0L}},
  475.     {"lisp",        NULL,   P_BOOL|P_IND|P_VI_DEF,
  476.                 (char_u *)PV_LISP,
  477.                 {(char_u *)FALSE, (char_u *)0L}},
  478.     {"list",        NULL,   P_BOOL|P_IND|P_VI_DEF|P_RBUF,
  479.                 (char_u *)PV_LIST,
  480.                 {(char_u *)FALSE, (char_u *)0L}},
  481.     {"magic",        NULL,   P_BOOL|P_VI_DEF,
  482.                 (char_u *)&p_magic,
  483.                 {(char_u *)TRUE, (char_u *)0L}},
  484.     {"makeef",        "mef",   P_STRING|P_EXPAND|P_VI_DEF,
  485.                 (char_u *)&p_mef,
  486.                 {(char_u *)MAKEEF, (char_u *)0L}},
  487.     {"makeprg",        "mp",   P_STRING|P_EXPAND|P_VI_DEF,
  488.                 (char_u *)&p_mp,
  489.                 {(char_u *)"make", (char_u *)0L}},
  490.     {"matchtime",   "mat",  P_NUM|P_VI_DEF,
  491.                 (char_u *)&p_mat,
  492.                 {(char_u *)5L, (char_u *)0L}},
  493.     {"maxmapdepth", "mmd",  P_NUM|P_VI_DEF,
  494.                 (char_u *)&p_mmd,
  495.                 {(char_u *)1000L, (char_u *)0L}},
  496.     {"maxmem",        "mm",   P_NUM|P_VI_DEF,
  497.                 (char_u *)&p_mm,
  498.                 {(char_u *)MAXMEM, (char_u *)0L}},
  499.     {"maxmemtot",   "mmt",  P_NUM|P_VI_DEF,
  500.                 (char_u *)&p_mmt,
  501.                 {(char_u *)MAXMEMTOT, (char_u *)0L}},
  502.     {"mesg",        NULL,   P_BOOL|P_VI_DEF,
  503.                 (char_u *)NULL,
  504.                 {(char_u *)FALSE, (char_u *)0L}},
  505.     {"modeline",    "ml",   P_BOOL|P_IND|P_VIM,
  506.                 (char_u *)PV_ML,
  507.                 {(char_u *)FALSE, (char_u *)TRUE}},
  508.     {"modelines",   "mls",  P_NUM|P_VI_DEF,
  509.                 (char_u *)&p_mls,
  510.                 {(char_u *)5L, (char_u *)0L}},
  511.     {"modified",    "mod",  P_BOOL|P_IND|P_NO_MKRC|P_VI_DEF|P_RSTAT,
  512.                 (char_u *)PV_MOD,
  513.                 {(char_u *)FALSE, (char_u *)0L}},
  514.     {"more",        NULL,   P_BOOL|P_VIM,
  515.                 (char_u *)&p_more,
  516.                 {(char_u *)FALSE, (char_u *)TRUE}},
  517.     {"mouse",        NULL,   P_STRING|P_VI_DEF,
  518.                 (char_u *)&p_mouse,
  519.                 {
  520. #if defined(MSDOS) || defined(WIN32)
  521.                 (char_u *)"a",
  522. #else
  523.                 (char_u *)"",
  524. #endif
  525.                 (char_u *)0L}},
  526.     {"mousehide",   "mh",   P_BOOL|P_VI_DEF,
  527. #ifdef USE_GUI
  528.                 (char_u *)&p_mh,
  529. #else
  530.                 (char_u *)NULL,
  531. #endif
  532.                 {(char_u *)FALSE, (char_u *)0L}},
  533.     {"mousetime",   "mouset",    P_NUM|P_VI_DEF,
  534.                 (char_u *)&p_mouset,
  535.                 {(char_u *)500L, (char_u *)0L}},
  536.     {"novice",        NULL,   P_BOOL|P_VI_DEF,
  537.                 (char_u *)NULL,
  538.                 {(char_u *)FALSE, (char_u *)0L}},
  539.     {"number",        "nu",   P_BOOL|P_IND|P_VI_DEF|P_RBUF,
  540.                 (char_u *)PV_NU,
  541.                 {(char_u *)FALSE, (char_u *)0L}},
  542.     {"nrformats",   "nf",   P_STRING|P_IND|P_ALLOCED|P_VI_DEF,
  543.                 (char_u *)PV_NF,
  544.                 {(char_u *)"octal,hex", (char_u *)0L}},
  545.     {"open",        NULL,   P_BOOL|P_VI_DEF,
  546.                 (char_u *)NULL,
  547.                 {(char_u *)FALSE, (char_u *)0L}},
  548.     {"optimize",    "opt",  P_BOOL|P_VI_DEF,
  549.                 (char_u *)NULL,
  550.                 {(char_u *)FALSE, (char_u *)0L}},
  551.     {"paragraphs",  "para", P_STRING|P_VI_DEF,
  552.                 (char_u *)&p_para,
  553.                 {(char_u *)"IPLPPPQPP LIpplpipbp", (char_u *)0L}},
  554.     {"paste",        NULL,   P_BOOL|P_VI_DEF,
  555.                 (char_u *)&p_paste,
  556.                 {(char_u *)FALSE, (char_u *)0L}},
  557.     {"patchmode",   "pm",   P_STRING|P_VI_DEF,
  558.                 (char_u *)&p_pm,
  559.                 {(char_u *)"", (char_u *)0L}},
  560.     {"path",        "pa",   P_STRING|P_EXPAND|P_VI_DEF,
  561.                 (char_u *)&p_path,
  562.                 {
  563. #if defined AMIGA || defined MSDOS || defined WIN32
  564.                 (char_u *)".,,",
  565. #else
  566. # if defined(__EMX__)
  567.                 (char_u *)".,/emx/include,,",
  568. # else /* Unix, probably */
  569.                 (char_u *)".,/usr/include,,",
  570. # endif
  571. #endif
  572.                 (char_u *)0L}},
  573.     {"prompt",        NULL,   P_BOOL|P_VI_DEF,
  574.                 (char_u *)NULL,
  575.                 {(char_u *)FALSE, (char_u *)0L}},
  576.     {"readonly",    "ro",   P_BOOL|P_IND|P_VI_DEF|P_RSTAT,
  577.                 (char_u *)PV_RO,
  578.                 {(char_u *)FALSE, (char_u *)0L}},
  579.     {"redraw",        NULL,   P_BOOL|P_VI_DEF,
  580.                 (char_u *)NULL,
  581.                 {(char_u *)FALSE, (char_u *)0L}},
  582.     {"remap",        NULL,   P_BOOL|P_VI_DEF,
  583.                 (char_u *)&p_remap,
  584.                 {(char_u *)TRUE, (char_u *)0L}},
  585.     {"report",        NULL,   P_NUM|P_VI_DEF,
  586.                 (char_u *)&p_report,
  587.                 {(char_u *)2L, (char_u *)0L}},
  588. #ifdef WIN32
  589.     {"restorescreen", "rs", P_BOOL|P_VI_DEF,
  590.                 (char_u *)&p_rs,
  591.                 {(char_u *)TRUE, (char_u *)0L}},
  592. #endif
  593. #ifdef RIGHTLEFT
  594.     {"revins",        "ri",   P_BOOL|P_VI_DEF|P_VIM,
  595.                 (char_u *)&p_ri,
  596.                 {(char_u *)FALSE, (char_u *)0L}},
  597.     {"rightleft",   "rl",   P_BOOL|P_IND|P_VI_DEF|P_RBUF,
  598.                 (char_u *)PV_RL,
  599.                 {(char_u *)FALSE, (char_u *)0L}},
  600. #endif
  601.     {"ruler",        "ru",   P_BOOL|P_VI_DEF|P_VIM|P_RSTAT,
  602.                 (char_u *)&p_ru,
  603.                 {(char_u *)FALSE, (char_u *)0L}},
  604.     {"scroll",        "scr",  P_NUM|P_IND|P_NO_MKRC|P_VI_DEF,
  605.                 (char_u *)PV_SCROLL,
  606.                 {(char_u *)12L, (char_u *)0L}},
  607.     {"scrolljump",  "sj",   P_NUM|P_VI_DEF|P_VIM,
  608.                 (char_u *)&p_sj,
  609.                 {(char_u *)1L, (char_u *)0L}},
  610.     {"scrolloff",   "so",   P_NUM|P_VI_DEF|P_VIM|P_RALL,
  611.                 (char_u *)&p_so,
  612.                 {(char_u *)0L, (char_u *)0L}},
  613.     {"sections",    "sect", P_STRING|P_VI_DEF,
  614.                 (char_u *)&p_sections,
  615.                 {(char_u *)"SHNHH HUnhsh", (char_u *)0L}},
  616.     {"secure",        NULL,   P_BOOL|P_VI_DEF,
  617.                 (char_u *)&p_secure,
  618.                 {(char_u *)FALSE, (char_u *)0L}},
  619.     {"shell",        "sh",   P_STRING|P_EXPAND|P_VI_DEF,
  620.                 (char_u *)&p_sh,
  621.                 {
  622. #if defined(MSDOS)
  623.                 (char_u *)"command",
  624. #else
  625. # if defined(WIN32)
  626.                 (char_u *)"",    /* set in set_init_1() */
  627. # else
  628. #  if defined(OS2)
  629.                 (char_u *)"cmd.exe",
  630. #  else
  631. #   if defined(ARCHIE)
  632.                 (char_u *)"gos",
  633. #   else
  634.                 (char_u *)"sh",
  635. #   endif
  636. #  endif
  637. # endif
  638. #endif
  639.                 (char_u *)0L}},
  640.     {"shellcmdflag","shcf", P_STRING|P_VI_DEF,
  641.                 (char_u *)&p_shcf,
  642.                 {
  643. #if defined(MSDOS) || defined(WIN32)
  644.                 (char_u *)"/c",
  645. #else
  646. # if defined(OS2)
  647.                 (char_u *)"/c",
  648. # else
  649.                 (char_u *)"-c",
  650. # endif
  651. #endif
  652.                 (char_u *)0L}},
  653.     {"shellpipe",   "sp",   P_STRING|P_VI_DEF,
  654.                 (char_u *)&p_sp,
  655.                 {
  656. #if defined(UNIX) || defined(OS2)
  657. # ifdef ARCHIE
  658.                 (char_u *)"2>",
  659. # else
  660.                 (char_u *)"| tee",
  661. # endif
  662. #else
  663.                 (char_u *)">",
  664. #endif
  665.                 (char_u *)0L}},
  666.     {"shellquote",  "shq",  P_STRING|P_VI_DEF,
  667.                 (char_u *)&p_shq,
  668.                 {(char_u *)"", (char_u *)0L}},
  669.     {"shellredir",  "srr",  P_STRING|P_VI_DEF,
  670.                 (char_u *)&p_srr,
  671.                 {(char_u *)">", (char_u *)0L}},
  672.     {"shelltype",   "st",   P_NUM|P_VI_DEF,
  673.                 (char_u *)&p_st,
  674.                 {(char_u *)0L, (char_u *)0L}},
  675.     {"shellxquote", "sxq",  P_STRING|P_VI_DEF,
  676.                 (char_u *)&p_sxq,
  677.                 {
  678. #if defined(UNIX) && defined(USE_SYSTEM) && !defined(__EMX__)
  679.                 (char_u *)"\"",
  680. #else
  681.                 (char_u *)"",
  682. #endif
  683.                 (char_u *)0L}},
  684.     {"shiftround",  "sr",   P_BOOL|P_VI_DEF|P_VIM,
  685.                 (char_u *)&p_sr,
  686.                 {(char_u *)FALSE, (char_u *)0L}},
  687.     {"shiftwidth",  "sw",   P_NUM|P_IND|P_VI_DEF,
  688.                 (char_u *)PV_SW,
  689.                 {(char_u *)8L, (char_u *)0L}},
  690.     {"shortmess",   "shm",  P_STRING|P_VI_DEF|P_VIM,
  691.                 (char_u *)&p_shm,
  692.                 {(char_u *)"", (char_u *)0L}},
  693.     {"shortname",   "sn",   P_BOOL|P_IND|P_VI_DEF,
  694. #ifdef SHORT_FNAME
  695.                 (char_u *)NULL,
  696. #else
  697.                 (char_u *)PV_SN,
  698. #endif
  699.                 {(char_u *)FALSE, (char_u *)0L}},
  700.     {"showbreak",   "sbr",  P_STRING|P_VI_DEF|P_RALL,
  701.                 (char_u *)&p_sbr,
  702.                 {(char_u *)"", (char_u *)0L}},
  703.     {"showcmd",        "sc",   P_BOOL|P_VIM,
  704.                 (char_u *)&p_sc,
  705.                 {(char_u *)FALSE,
  706. #ifdef UNIX
  707.                 (char_u *)FALSE
  708. #else
  709.                 (char_u *)TRUE
  710. #endif
  711.                 }},
  712.     {"showmatch",   "sm",   P_BOOL|P_VI_DEF,
  713.                 (char_u *)&p_sm,
  714.                 {(char_u *)FALSE, (char_u *)0L}},
  715.     {"showmode",    "smd",  P_BOOL|P_VIM,
  716.                 (char_u *)&p_smd,
  717.                 {(char_u *)FALSE, (char_u *)TRUE}},
  718.     {"sidescroll",  "ss",   P_NUM|P_VI_DEF,
  719.                 (char_u *)&p_ss,
  720.                 {(char_u *)0L, (char_u *)0L}},
  721.     {"slowopen",    "slow", P_BOOL|P_VI_DEF,
  722.                 (char_u *)NULL,
  723.                 {(char_u *)FALSE, (char_u *)0L}},
  724.     {"smartcase",   "scs",  P_BOOL|P_VI_DEF|P_VIM,
  725.                 (char_u *)&p_scs,
  726.                 {(char_u *)FALSE, (char_u *)0L}},
  727. #ifdef SMARTINDENT
  728.     {"smartindent", "si",   P_BOOL|P_IND|P_VI_DEF|P_VIM,
  729.                 (char_u *)PV_SI,
  730.                 {(char_u *)FALSE, (char_u *)0L}},
  731. #endif
  732.     {"smarttab",    "sta",  P_BOOL|P_VI_DEF|P_VIM,
  733.                 (char_u *)&p_sta,
  734.                 {(char_u *)FALSE, (char_u *)0L}},
  735.     {"softtabstop", "sts",  P_NUM|P_IND|P_VI_DEF|P_VIM,
  736.                 (char_u *)PV_STS,
  737.                 {(char_u *)0L, (char_u *)0L}},
  738.     {"sourceany",   NULL,   P_BOOL|P_VI_DEF,
  739.                 (char_u *)NULL,
  740.                 {(char_u *)FALSE, (char_u *)0L}},
  741.     {"splitbelow",  "sb",   P_BOOL|P_VI_DEF,
  742.                 (char_u *)&p_sb,
  743.                 {(char_u *)FALSE, (char_u *)0L}},
  744.     {"startofline", "sol",  P_BOOL|P_VI_DEF|P_VIM,
  745.                 (char_u *)&p_sol,
  746.                 {(char_u *)TRUE, (char_u *)0L}},
  747.     {"suffixes",    "su",   P_STRING|P_VI_DEF,
  748.                 (char_u *)&p_su,
  749.                 {(char_u *)".bak,~,.o,.h,.info,.swp",
  750.                 (char_u *)0L}},
  751.     {"swapsync",    "sws",  P_STRING|P_VI_DEF,
  752.                 (char_u *)&p_sws,
  753.                 {(char_u *)"fsync", (char_u *)0L}},
  754.     {"tabstop",        "ts",   P_NUM|P_IND|P_VI_DEF|P_RBUF,
  755.                 (char_u *)PV_TS,
  756.                 {(char_u *)8L, (char_u *)0L}},
  757.     {"tagbsearch",  "tbs",   P_BOOL|P_VI_DEF,
  758.                 (char_u *)&p_tbs,
  759.                 {(char_u *)TRUE, (char_u *)0L}},
  760.     {"taglength",   "tl",   P_NUM|P_VI_DEF,
  761.                 (char_u *)&p_tl,
  762.                 {(char_u *)0L, (char_u *)0L}},
  763.     {"tagrelative", "tr",   P_BOOL|P_VIM,
  764.                 (char_u *)&p_tr,
  765.                 {(char_u *)FALSE, (char_u *)TRUE}},
  766.     {"tags",        "tag",  P_STRING|P_EXPAND|P_VI_DEF,
  767.                 (char_u *)&p_tags,
  768.                 {
  769. #ifdef EMACS_TAGS
  770.                 (char_u *)"./tags,./TAGS,tags,TAGS",
  771. #else
  772.                 (char_u *)"./tags,tags",
  773. #endif
  774.                 (char_u *)0L}},
  775.     {"tagstack",    "tgst", P_BOOL|P_VI_DEF,
  776.                 (char_u *)NULL,
  777.                 {(char_u *)FALSE, (char_u *)0L}},
  778.     {"term",        NULL,   P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL,
  779.                 (char_u *)&T_NAME,
  780.                 {(char_u *)"", (char_u *)0L}},
  781.     {"terse",        NULL,   P_BOOL|P_VI_DEF,
  782.                 (char_u *)&p_terse,
  783.                 {(char_u *)FALSE, (char_u *)0L}},
  784.     {"textauto",    "ta",   P_BOOL|P_VIM,
  785.                 (char_u *)&p_ta,
  786.                 {(char_u *)TA_DFLT, (char_u *)TRUE}},
  787.     {"textmode",    "tx",   P_BOOL|P_IND|P_VI_DEF,
  788.                 (char_u *)PV_TX,
  789.                 {
  790. #ifdef USE_CRNL
  791.                 (char_u *)TRUE,
  792. #else
  793.                 (char_u *)FALSE,
  794. #endif
  795.                 (char_u *)0L}},
  796.     {"textwidth",   "tw",   P_NUM|P_IND|P_VI_DEF|P_VIM,
  797.                 (char_u *)PV_TW,
  798.                 {(char_u *)0L, (char_u *)0L}},
  799.     {"tildeop",        "top",  P_BOOL|P_VI_DEF|P_VIM,
  800.                 (char_u *)&p_to,
  801.                 {(char_u *)FALSE, (char_u *)0L}},
  802.     {"timeout",        "to",   P_BOOL|P_VI_DEF,
  803.                 (char_u *)&p_timeout,
  804.                 {(char_u *)TRUE, (char_u *)0L}},
  805.     {"timeoutlen",  "tm",   P_NUM|P_VI_DEF,
  806.                 (char_u *)&p_tm,
  807.                 {(char_u *)1000L, (char_u *)0L}},
  808.     {"title",        NULL,   P_BOOL|P_VI_DEF,
  809.                 (char_u *)&p_title,
  810.                 {(char_u *)FALSE, (char_u *)0L}},
  811.     {"titlelen",    NULL,   P_NUM|P_VI_DEF,
  812.                 (char_u *)&p_titlelen,
  813.                 {(char_u *)85L, (char_u *)0L}},
  814.     {"titlestring", NULL,   P_STRING|P_VI_DEF,
  815.                 (char_u *)&p_titlestring,
  816.                 {(char_u *)"", (char_u *)0L}},
  817.     {"ttimeout",    NULL,   P_BOOL|P_VI_DEF|P_VIM,
  818.                 (char_u *)&p_ttimeout,
  819.                 {(char_u *)FALSE, (char_u *)0L}},
  820.     {"ttimeoutlen", "ttm",  P_NUM|P_VI_DEF,
  821.                 (char_u *)&p_ttm,
  822.                 {(char_u *)-1L, (char_u *)0L}},
  823.     {"ttybuiltin",  "tbi",  P_BOOL|P_VI_DEF,
  824.                 (char_u *)&p_tbi,
  825.                 {(char_u *)TRUE, (char_u *)0L}},
  826.     {"ttyfast",        "tf",   P_BOOL|P_NO_MKRC|P_VI_DEF,
  827.                 (char_u *)&p_tf,
  828.                 {(char_u *)FALSE, (char_u *)0L}},
  829.     {"ttyscroll",   "tsl",  P_NUM|P_VI_DEF,
  830.                 (char_u *)&p_ttyscroll,
  831.                 {(char_u *)999L, (char_u *)0L}},
  832.     {"ttytype",        "tty",  P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL,
  833.                 (char_u *)&T_NAME,
  834.                 {(char_u *)"", (char_u *)0L}},
  835.     {"undolevels",  "ul",   P_NUM|P_VI_DEF,
  836.                 (char_u *)&p_ul,
  837.                 {
  838. #if defined(UNIX) || defined(WIN32) || defined(OS2)
  839.                 (char_u *)1000L,
  840. #else
  841.                 (char_u *)100L,
  842. #endif
  843.                 (char_u *)0L}},
  844.     {"updatecount", "uc",   P_NUM|P_VI_DEF,
  845.                 (char_u *)&p_uc,
  846.                 {(char_u *)200L, (char_u *)0L}},
  847.     {"updatetime",  "ut",   P_NUM|P_VI_DEF,
  848.                 (char_u *)&p_ut,
  849.                 {(char_u *)4000L, (char_u *)0L}},
  850.     {"verbose",        "vbs",  P_NUM|P_VI_DEF,
  851.                 (char_u *)&p_verbose,
  852.                 {(char_u *)0L, (char_u *)0L}},
  853.     {"viminfo",        "vi",   P_STRING|P_VI_DEF,
  854. #ifdef VIMINFO
  855.                 (char_u *)&p_viminfo,
  856. #else
  857.                 (char_u *)NULL,
  858. #endif /* VIMINFO */
  859.                 {(char_u *)"", (char_u *)0L}},
  860.     {"visualbell",  "vb",   P_BOOL|P_VI_DEF,
  861.                 (char_u *)&p_vb,
  862.                 {(char_u *)FALSE, (char_u *)0L}},
  863.     {"w300",        NULL,   P_NUM|P_VI_DEF,
  864.                 (char_u *)NULL,
  865.                 {(char_u *)0L, (char_u *)0L}},
  866.     {"w1200",        NULL,   P_NUM|P_VI_DEF,
  867.                 (char_u *)NULL,
  868.                 {(char_u *)0L, (char_u *)0L}},
  869.     {"w9600",        NULL,   P_NUM|P_VI_DEF,
  870.                 (char_u *)NULL,
  871.                 {(char_u *)0L, (char_u *)0L}},
  872.     {"warn",        NULL,   P_BOOL|P_VI_DEF,
  873.                 (char_u *)&p_warn,
  874.                 {(char_u *)TRUE, (char_u *)0L}},
  875.     {"weirdinvert", "wiv",  P_BOOL|P_VI_DEF|P_RALL,
  876.                 (char_u *)&p_wiv,
  877.                 {(char_u *)FALSE, (char_u *)0L}},
  878.     {"whichwrap",   "ww",   P_STRING|P_VIM,
  879.                 (char_u *)&p_ww,
  880.                 {(char_u *)"", (char_u *)"b,s"}},
  881.     {"wildchar",    "wc",   P_NUM|P_VIM,
  882.                 (char_u *)&p_wc,
  883.                 {(char_u *)(long)Ctrl('E'), (char_u *)(long)TAB}},
  884.     {"window",        "wi",   P_NUM|P_VI_DEF,
  885.                 (char_u *)NULL,
  886.                 {(char_u *)0L, (char_u *)0L}},
  887.     {"winheight",   "wh",   P_NUM|P_VI_DEF,
  888.                 (char_u *)&p_wh,
  889.                 {(char_u *)0L, (char_u *)0L}},
  890.     {"wrap",        NULL,   P_BOOL|P_IND|P_VI_DEF|P_RBUF,
  891.                 (char_u *)PV_WRAP,
  892.                 {(char_u *)TRUE, (char_u *)0L}},
  893.     {"wrapmargin",  "wm",   P_NUM|P_IND|P_VI_DEF,
  894.                 (char_u *)PV_WM,
  895.                 {(char_u *)0L, (char_u *)0L}},
  896.     {"wrapscan",    "ws",   P_BOOL|P_VI_DEF,
  897.                 (char_u *)&p_ws,
  898.                 {(char_u *)TRUE, (char_u *)0L}},
  899.     {"writeany",    "wa",   P_BOOL|P_VI_DEF,
  900.                 (char_u *)&p_wa,
  901.                 {(char_u *)FALSE, (char_u *)0L}},
  902.     {"writebackup", "wb",   P_BOOL|P_VI_DEF|P_VIM,
  903.                 (char_u *)&p_wb,
  904.                 {
  905. #ifdef WRITEBACKUP
  906.                 (char_u *)TRUE,
  907. #else
  908.                 (char_u *)FALSE,
  909. #endif
  910.                 (char_u *)0L}},
  911.     {"writedelay",  "wd",   P_NUM|P_VI_DEF,
  912.                 (char_u *)&p_wd,
  913.                 {(char_u *)0L, (char_u *)0L}},
  914.  
  915. /* terminal output codes */
  916. #define p_term(sss, vvv)   {sss, NULL, P_STRING|P_VI_DEF|P_RALL, \
  917.                 (char_u *)&vvv, \
  918.                 {(char_u *)"", (char_u *)0L}},
  919.  
  920.     p_term("t_AB", T_CAB)
  921.     p_term("t_AF", T_CAF)
  922.     p_term("t_AL", T_CAL)
  923.     p_term("t_al", T_AL)
  924.     p_term("t_bc", T_BC)
  925.     p_term("t_cd", T_CD)
  926.     p_term("t_ce", T_CE)
  927.     p_term("t_cl", T_CL)
  928.     p_term("t_cm", T_CM)
  929.     p_term("t_Co", T_CCO)
  930.     p_term("t_CS", T_CCS)
  931.     p_term("t_cs", T_CS)
  932.     p_term("t_da", T_DA)
  933.     p_term("t_db", T_DB)
  934.     p_term("t_DL", T_CDL)
  935.     p_term("t_dl", T_DL)
  936.     p_term("t_ke", T_KE)
  937.     p_term("t_ks", T_KS)
  938.     p_term("t_le", T_LE)
  939.     p_term("t_mb", T_MB)
  940.     p_term("t_md", T_MD)
  941.     p_term("t_me", T_ME)
  942.     p_term("t_mr", T_MR)
  943.     p_term("t_ms", T_MS)
  944.     p_term("t_nd", T_ND)
  945.     p_term("t_op", T_OP)
  946.     p_term("t_RI", T_CRI)
  947.     p_term("t_Sb", T_CSB)
  948.     p_term("t_Sf", T_CSF)
  949.     p_term("t_se", T_SE)
  950.     p_term("t_so", T_SO)
  951.     p_term("t_sr", T_SR)
  952.     p_term("t_te", T_TE)
  953.     p_term("t_ti", T_TI)
  954.     p_term("t_ue", T_UE)
  955.     p_term("t_us", T_US)
  956.     p_term("t_vb", T_VB)
  957.     p_term("t_ve", T_VE)
  958.     p_term("t_vi", T_VI)
  959.     p_term("t_vs", T_VS)
  960.     p_term("t_xs", T_XS)
  961.     p_term("t_ZH", T_CZH)
  962.     p_term("t_ZR", T_CZR)
  963.  
  964. /* terminal key codes are not in here */
  965.  
  966.     {NULL, NULL, 0, NULL, {NULL, NULL}}        /* end marker */
  967. };
  968.  
  969. #define PARAM_COUNT (sizeof(options) / sizeof(struct vimoption))
  970.  
  971. static char *(p_bg_values[]) = {"light", "dark", NULL};
  972. static char *(p_nf_values[]) = {"octal", "hex", NULL};
  973. static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
  974.  
  975. static void set_option_default __ARGS((int, int));
  976. static void set_options_default __ARGS((int dofree));
  977. static void illegal_char __ARGS((char_u *, int));
  978. static void did_set_title __ARGS((int icon));
  979. static char_u *option_expand __ARGS((int));
  980. static void set_string_option __ARGS((int opt_idx, char_u *value));
  981. static char_u *did_set_string_option __ARGS((int opt_idx, char_u **varp, int new_value_alloced, char_u *oldval, char_u *errbuf));
  982. static char_u *set_bool_option __ARGS((int opt_idx, char_u *varp, int value));
  983. static char_u *set_num_option __ARGS((int opt_idx, char_u *varp, long value, char_u *errbuf));
  984. static void check_redraw __ARGS((int flags));
  985. static int findoption __ARGS((char_u *));
  986. static int find_key_option __ARGS((char_u *));
  987. static void showoptions __ARGS((int));
  988. static int option_not_default __ARGS((struct vimoption *));
  989. static void showoneopt __ARGS((struct vimoption *));
  990. static int  istermoption __ARGS((struct vimoption *));
  991. static char_u *get_varp __ARGS((struct vimoption *));
  992. static void option_value2string __ARGS((struct vimoption *));
  993. #ifdef HAVE_LANGMAP
  994. static void langmap_init __ARGS((void));
  995. static void langmap_set __ARGS((void));
  996. #endif
  997. static void paste_option_changed __ARGS((void));
  998. static void compatible_set __ARGS((void));
  999. static void fill_breakat_flags __ARGS((void));
  1000. static int check_opt_strings __ARGS((char_u *val, char **values, int));
  1001.  
  1002. /*
  1003.  * Initialize the options, first part.
  1004.  *
  1005.  * Called only once from main(), just after creating the first buffer.
  1006.  */
  1007.     void
  1008. set_init_1()
  1009. {
  1010.     char_u  *p;
  1011.     int        opt_idx;
  1012.     long    n;
  1013.  
  1014. #ifdef HAVE_LANGMAP
  1015.     langmap_init();
  1016. #endif
  1017.  
  1018.     /* Be Vi compatible by default */
  1019.     p_cp = TRUE;
  1020.  
  1021.     /*
  1022.      * Find default value for 'shell' option.
  1023.      */
  1024.     if ((p = vim_getenv((char_u *)"SHELL")) != NULL
  1025. #if defined(MSDOS) || defined(WIN32) || defined(OS2)
  1026. # ifdef __EMX__
  1027.         || (p = vim_getenv((char_u *)"EMXSHELL")) != NULL
  1028. # endif
  1029.         || (p = vim_getenv((char_u *)"COMSPEC")) != NULL
  1030. # ifdef WIN32
  1031.         || (p = default_shell()) != NULL
  1032. # endif
  1033. #endif
  1034.                                 )
  1035.     {
  1036.     set_string_default("sh", p);
  1037.     }
  1038.  
  1039.     /*
  1040.      * 'maxmemtot' and 'maxmem' may have to be adjusted for available memory
  1041.      */
  1042.     opt_idx = findoption((char_u *)"maxmemtot");
  1043.     if (options[opt_idx].def_val[VI_DEFAULT] == (char_u *)0L)
  1044.     {
  1045.     n = (mch_avail_mem(FALSE) >> 11);
  1046.     options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
  1047.     opt_idx = findoption((char_u *)"maxmem");
  1048.     if ((long)options[opt_idx].def_val[VI_DEFAULT] > n
  1049.               || (long)options[opt_idx].def_val[VI_DEFAULT] == 0L)
  1050.         options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
  1051.     }
  1052.  
  1053. #ifdef USE_GUI_WIN32
  1054.     /* force 'shortname' for Win32s */
  1055.     if (gui_is_win32s())
  1056.     options[findoption((char_u *)"shortname")].def_val[VI_DEFAULT] =
  1057.                                    (char_u *)TRUE;
  1058. #endif
  1059.  
  1060.     /*
  1061.      * set all the options (except the terminal options) to their default value
  1062.      */
  1063.     set_options_default(FALSE);
  1064.  
  1065. #ifdef USE_GUI
  1066.     if (found_reverse_arg)
  1067.     set_option_value((char_u *)"bg", 0L, (char_u *)"dark");
  1068. #endif
  1069.  
  1070.     curbuf->b_p_initialized = TRUE;
  1071.     check_buf_options(curbuf);
  1072.     check_options();
  1073.  
  1074.     /*
  1075.      * initialize the table for 'iskeyword' et.al.
  1076.      * Must be before option_expand(), because that one needs vim_isIDc()
  1077.      */
  1078.     init_chartab();
  1079.  
  1080.     /*
  1081.      * initialize the table for 'breakat'.
  1082.      */
  1083.     fill_breakat_flags();
  1084.  
  1085.     /*
  1086.      * Expand environment variables and things like "~" for the defaults.
  1087.      * If option_expand() returns non-NULL the variable is expanded. This can
  1088.      * only happen for non-indirect options.
  1089.      * Also set the default to the expanded value, so ":set" does not list
  1090.      * them. Don't set the P_ALLOCED flag, because we don't want to free the
  1091.      * default.
  1092.      */
  1093.     for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
  1094.     {
  1095.     p = option_expand(opt_idx);
  1096.     if (p != NULL)
  1097.     {
  1098.         *(char_u **)options[opt_idx].var = p;
  1099.         /* VIMEXP
  1100.          * Defaults for all expanded options are currently the same for Vi
  1101.          * and Vim.  When this changes, add some code here!  Also need to
  1102.          * split P_DEF_ALLOCED in two.
  1103.          */
  1104.         options[opt_idx].def_val[VI_DEFAULT] = p;
  1105.         options[opt_idx].flags |= P_DEF_ALLOCED;
  1106.     }
  1107.     }
  1108.  
  1109.     /* Initialize the highlight_attr[] table. */
  1110.     highlight_changed();
  1111.  
  1112.     curbuf->b_start_ffc = *curbuf->b_p_ff;    /* Buffer is unchanged */
  1113. }
  1114.  
  1115. /*
  1116.  * Set an option to its default value.
  1117.  */
  1118.     static void
  1119. set_option_default(opt_idx, dofree)
  1120.     int        opt_idx;
  1121.     int        dofree;    /* TRUE when old value can be freed */
  1122. {
  1123.     char_u    *varp;        /* pointer to variable for current option */
  1124.     int        dvi;        /* index in def_val[] */
  1125.     int        flags;
  1126.  
  1127.     varp = get_varp(&(options[opt_idx]));
  1128.     flags = options[opt_idx].flags;
  1129.     if (varp != NULL)        /* nothing to do for hidden option */
  1130.     {
  1131.     if ((flags & P_VI_DEF) || p_cp)
  1132.         dvi = VI_DEFAULT;
  1133.     else
  1134.         dvi = VIM_DEFAULT;
  1135.     if (flags & P_STRING)
  1136.     {
  1137.         /* indirect options are always in allocated memory */
  1138.         if (flags & P_IND)
  1139.         set_string_option_direct(NULL, opt_idx,
  1140.                       options[opt_idx].def_val[dvi], dofree);
  1141.         else
  1142.         {
  1143.         if (dofree && (flags & P_ALLOCED))
  1144.             free_string_option(*(char_u **)(varp));
  1145.         *(char_u **)varp = options[opt_idx].def_val[dvi];
  1146.         options[opt_idx].flags &= ~P_ALLOCED;
  1147.         }
  1148.     }
  1149.     else if (flags & P_NUM)
  1150.         *(long *)varp = (long)options[opt_idx].def_val[dvi];
  1151.     else    /* P_BOOL */
  1152.         /* the cast to long is required for Manx C */
  1153.         *(int *)varp = (int)(long)options[opt_idx].def_val[dvi];
  1154.     }
  1155. }
  1156.  
  1157. /*
  1158.  * Set all options (except terminal options) to their default value.
  1159.  */
  1160.     static void
  1161. set_options_default(dofree)
  1162.     int        dofree;        /* may free old value */
  1163. {
  1164.     int        i;
  1165.  
  1166.     for (i = 0; !istermoption(&options[i]); i++)
  1167.     if (!(options[i].flags & P_NODEFAULT))
  1168.         set_option_default(i, dofree);
  1169. }
  1170.  
  1171. /*
  1172.  * Set the Vi-default value of a string option.
  1173.  * Used for 'sh' and 'term'.
  1174.  */
  1175.     void
  1176. set_string_default(name, val)
  1177.     char    *name;
  1178.     char_u  *val;
  1179. {
  1180.     char_u    *p;
  1181.     int        opt_idx;
  1182.  
  1183.     p = vim_strsave(val);
  1184.     if (p != NULL)        /* we don't want a NULL */
  1185.     {
  1186.     opt_idx = findoption((char_u *)name);
  1187.     if (options[opt_idx].flags & P_DEF_ALLOCED)
  1188.         vim_free(options[opt_idx].def_val[VI_DEFAULT]);
  1189.     options[opt_idx].def_val[VI_DEFAULT] = p;
  1190.     options[opt_idx].flags |= P_DEF_ALLOCED;
  1191.     }
  1192. }
  1193.  
  1194. /*
  1195.  * Set the Vi-default value of a number option.
  1196.  * Used for 'lines' and 'columns'.
  1197.  */
  1198.     void
  1199. set_number_default(name, val)
  1200.     char    *name;
  1201.     long    val;
  1202. {
  1203.     options[findoption((char_u *)name)].def_val[VI_DEFAULT] = (char_u *)val;
  1204. }
  1205.  
  1206. /*
  1207.  * Initialize the options, part two: After getting Rows and Columns and
  1208.  * setting 'term'.
  1209.  */
  1210.     void
  1211. set_init_2()
  1212. {
  1213.     /*
  1214.      * 'scroll' defaults to half the window height. Note that this default is
  1215.      * wrong when the window height changes.
  1216.      */
  1217.     options[findoption((char_u *)"scroll")].def_val[VI_DEFAULT]
  1218.                           = (char_u *)((long_u)Rows >> 1);
  1219.     comp_col();
  1220.  
  1221. #if !((defined(MSDOS) || defined(OS2) || defined(WIN32)) && !defined(USE_GUI))
  1222.     {
  1223.     int    idx4;
  1224.  
  1225.     /*
  1226.      * Try guessing the value of 'background', depending on the terminal
  1227.      * name.  Only need to check for terminals with a dark background,
  1228.      * that can handle color.
  1229.      */
  1230.     idx4 = findoption((char_u *)"bg");
  1231.     if (!(options[idx4].flags & P_WAS_SET))
  1232.     {
  1233.         if (STRCMP(T_NAME, "linux") == 0)        /* linux console */
  1234.         set_string_option_direct(NULL, idx4, (char_u *)"dark", TRUE);
  1235.     }
  1236.     }
  1237. #endif
  1238. }
  1239.  
  1240. /*
  1241.  * Initialize the options, part three: After reading the .vimrc
  1242.  */
  1243.     void
  1244. set_init_3()
  1245. {
  1246. #if defined(UNIX) || defined(OS2)
  1247. /*
  1248.  * Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
  1249.  * This is done after other initializations, where 'shell' might have been
  1250.  * set, but only if they have not been set before.
  1251.  */
  1252.     char_u  *p;
  1253.     int        idx1;
  1254.     int        idx2;
  1255.     int        do_sp;
  1256.     int        do_srr;
  1257.  
  1258.     idx1 = findoption((char_u *)"sp");
  1259.     idx2 = findoption((char_u *)"srr");
  1260.     do_sp = !(options[idx1].flags & P_WAS_SET);
  1261.     do_srr = !(options[idx2].flags & P_WAS_SET);
  1262.  
  1263.     /*
  1264.      * Isolate the name of the shell:
  1265.      * - Skip beyond any path.  E.g., "/usr/bin/csh -f" -> "csh -f".
  1266.      * - Remove any argument.  E.g., "csh -f" -> "csh".
  1267.      */
  1268.     p = gettail(p_sh);
  1269.     p = vim_strnsave(p, skiptowhite(p) - p);
  1270.     if (p != NULL)
  1271.     {
  1272.     /*
  1273.      * Default for p_sp is "| tee", for p_srr is ">".
  1274.      * For known shells it is changed here to include stderr.
  1275.      */
  1276.     if (       fnamecmp(p, "csh") == 0
  1277.         || fnamecmp(p, "tcsh") == 0
  1278. # ifdef OS2        /* also check with .exe extension */
  1279.         || fnamecmp(p, "csh.exe") == 0
  1280.         || fnamecmp(p, "tcsh.exe") == 0
  1281. # endif
  1282.        )
  1283.     {
  1284.         if (do_sp)
  1285.         {
  1286.         p_sp = (char_u *)"|& tee";
  1287.         options[idx1].def_val[VI_DEFAULT] = p_sp;
  1288.         }
  1289.         if (do_srr)
  1290.         {
  1291.         p_srr = (char_u *)">&";
  1292.         options[idx2].def_val[VI_DEFAULT] = p_srr;
  1293.         }
  1294.     }
  1295.     else
  1296. # ifndef OS2    /* Always use bourne shell style redirection if we reach this */
  1297.         if (       STRCMP(p, "sh") == 0
  1298.             || STRCMP(p, "ksh") == 0
  1299.             || STRCMP(p, "zsh") == 0
  1300.             || STRCMP(p, "bash") == 0)
  1301. # endif
  1302.         {
  1303.         if (do_sp)
  1304.         {
  1305.             p_sp = (char_u *)"2>&1| tee";
  1306.             options[idx1].def_val[VI_DEFAULT] = p_sp;
  1307.         }
  1308.         if (do_srr)
  1309.         {
  1310.             p_srr = (char_u *)">%s 2>&1";
  1311.             options[idx2].def_val[VI_DEFAULT] = p_srr;
  1312.         }
  1313.         }
  1314.     vim_free(p);
  1315.     }
  1316. #endif
  1317.  
  1318. #if defined(MSDOS) || defined(WIN32) || defined(OS2)
  1319.     /*
  1320.      * Set 'shellcmdflag and 'shellquote' depending on the 'shell' option.
  1321.      * This is done after other initializations, where 'shell' might have been
  1322.      * set, but only if they have not been set before.  Default for p_shcf is
  1323.      * "/c", for p_shq is "".  For "sh" like  shells it is changed here to
  1324.      * "-c" and "\"", but not for DJGPP, because it starts the shell without
  1325.      * command.com.  And for Win32 we need to set p_sxq instead.
  1326.      */
  1327.     if (strstr((char *)p_sh, "sh") != NULL)
  1328.     {
  1329.     int    idx3;
  1330.  
  1331.     idx3 = findoption((char_u *)"shcf");
  1332.     if (!(options[idx3].flags & P_WAS_SET))
  1333.     {
  1334.         p_shcf = (char_u *)"-c";
  1335.         options[idx3].def_val[VI_DEFAULT] = p_shcf;
  1336.     }
  1337.  
  1338. # ifndef DJGPP
  1339. #  ifdef WIN32
  1340.     /* Somehow Win32 requires the quotes around the redirection too */
  1341.     idx3 = findoption((char_u *)"sxq");
  1342.     if (!(options[idx3].flags & P_WAS_SET))
  1343.     {
  1344.         p_sxq = (char_u *)"\"";
  1345.         options[idx3].def_val[VI_DEFAULT] = p_sxq;
  1346.     }
  1347. #  else
  1348.     idx3 = findoption((char_u *)"shq");
  1349.     if (!(options[idx3].flags & P_WAS_SET))
  1350.     {
  1351.         p_shq = (char_u *)"\"";
  1352.         options[idx3].def_val[VI_DEFAULT] = p_shq;
  1353.     }
  1354. #  endif
  1355. # endif
  1356.     }
  1357. #endif
  1358.  
  1359.     set_title_defaults();
  1360. }
  1361.  
  1362. #ifdef USE_GUI
  1363. /*
  1364.  * Option initializations that can only be done after opening the GUI window.
  1365.  */
  1366.     void
  1367. init_gui_options()
  1368. {
  1369.     int        idx;
  1370.     int        tt;
  1371.  
  1372.     /* Set the 'background' option according to the lightness of the
  1373.      * background color. */
  1374.     idx = findoption((char_u *)"bg");
  1375.     if (!(options[idx].flags & P_WAS_SET)
  1376.                    && gui_mch_get_lightness(gui.back_pixel) < 127)
  1377.     {
  1378.     /* Full_screen must be TRUE to get the side effect of changing the
  1379.      * defaults for the highlighting.  Restore it just in case. */
  1380.     tt = full_screen;
  1381.     full_screen = TRUE;
  1382.     set_option_value((char_u *)"bg", 0L, (char_u *)"dark");
  1383.     highlight_changed();
  1384.     full_screen = tt;
  1385.     }
  1386. }
  1387. #endif
  1388.  
  1389. /*
  1390.  * 'title' and 'icon' only default to true if they have not been set or reset
  1391.  * in .vimrc and we can read the old value.
  1392.  * When 'title' and 'icon' have been reset in .vimrc, we won't even check if
  1393.  * they can be reset.  This reduces startup time when using X on a remote
  1394.  * machine.
  1395.  */
  1396.     void
  1397. set_title_defaults()
  1398. {
  1399.     int        idx1;
  1400.     long    val;
  1401.  
  1402.     idx1 = findoption((char_u *)"title");
  1403.     if (!(options[idx1].flags & P_WAS_SET))
  1404.     {
  1405.     val = ui_can_restore_title();
  1406.     options[idx1].def_val[VI_DEFAULT] = (char_u *)val;
  1407.     p_title = val;
  1408.     }
  1409.     idx1 = findoption((char_u *)"icon");
  1410.     if (!(options[idx1].flags & P_WAS_SET))
  1411.     {
  1412.     val = ui_can_restore_icon();
  1413.     options[idx1].def_val[VI_DEFAULT] = (char_u *)val;
  1414.     p_icon = val;
  1415.     }
  1416. }
  1417.  
  1418. /*
  1419.  * Parse 'arg' for option settings.
  1420.  *
  1421.  * 'arg' may be IObuff, but only when no errors can be present and option
  1422.  * does not need to be expanded with option_expand().
  1423.  *
  1424.  * return FAIL if errors are detected, OK otherwise
  1425.  */
  1426.     int
  1427. do_set(arg)
  1428.     char_u    *arg;    /* option string (may be written to!) */
  1429. {
  1430.     int        opt_idx;
  1431.     char_u    *errmsg;
  1432.     char_u    errbuf[80];
  1433.     char_u    *startarg;
  1434.     int        prefix;    /* 1: nothing, 0: "no", 2: "inv" in front of name */
  1435.     int        nextchar;        /* next non-white char after option name */
  1436.     int        afterchar;        /* character just after option name */
  1437.     int        len;
  1438.     int        i;
  1439.     long    value;
  1440.     int        key;
  1441.     int        flags;            /* flags for current option */
  1442.     char_u    *varp = NULL;        /* pointer to variable for current option */
  1443.     int        errcnt = 0;        /* number of errornous entries */
  1444.     int        did_show = FALSE;   /* already showed one value */
  1445.  
  1446.     if (*arg == NUL)
  1447.     {
  1448.     showoptions(0);
  1449.     return OK;
  1450.     }
  1451.  
  1452.     while (*arg)    /* loop to process all options */
  1453.     {
  1454.     errmsg = NULL;
  1455.     startarg = arg;        /* remember for error message */
  1456.  
  1457.     if (STRNCMP(arg, "all", 3) == 0)
  1458.     {
  1459.         /*
  1460.          * ":set all"  show all options.
  1461.          * ":set all&" set all options to their default value.
  1462.          */
  1463.         arg += 3;
  1464.         if (*arg == '&')
  1465.         {
  1466.         ++arg;
  1467.         set_options_default(TRUE);
  1468.         }
  1469.         else
  1470.         showoptions(1);
  1471.     }
  1472.     else if (STRNCMP(arg, "termcap", 7) == 0)
  1473.     {
  1474.         showoptions(2);
  1475.         show_termcodes();
  1476.         arg += 7;
  1477.     }
  1478.     else
  1479.     {
  1480.         prefix = 1;
  1481.         if (STRNCMP(arg, "no", 2) == 0)
  1482.         {
  1483.         prefix = 0;
  1484.         arg += 2;
  1485.         }
  1486.         else if (STRNCMP(arg, "inv", 3) == 0)
  1487.         {
  1488.         prefix = 2;
  1489.         arg += 3;
  1490.         }
  1491.         /* find end of name */
  1492.         if (*arg == '<')
  1493.         {
  1494.         opt_idx = -1;
  1495.         /* look out for <t_>;> */
  1496.         if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4])
  1497.             len = 5;
  1498.         else
  1499.         {
  1500.             len = 1;
  1501.             while (arg[len] != NUL && arg[len] != '>')
  1502.             ++len;
  1503.         }
  1504.         if (arg[len] != '>')
  1505.         {
  1506.             errmsg = e_invarg;
  1507.             goto skip;
  1508.         }
  1509.         nextchar = arg[len];
  1510.         arg[len] = NUL;                /* put NUL after name */
  1511.         if (arg[1] == 't' && arg[2] == '_') /* could be term code */
  1512.             opt_idx = findoption(arg + 1);
  1513.         arg[len++] = nextchar;            /* restore nextchar */
  1514.         key = 0;
  1515.         if (opt_idx == -1)
  1516.             key = find_key_option(arg + 1);
  1517.         nextchar = arg[len];
  1518.         }
  1519.         else
  1520.         {
  1521.         len = 0;
  1522.         /*
  1523.          * The two characters after "t_" may not be alphanumeric.
  1524.          */
  1525.         if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
  1526.         {
  1527.             len = 4;
  1528.         }
  1529.         else
  1530.         {
  1531.             while (isalnum(arg[len]) || arg[len] == '_')
  1532.             ++len;
  1533.         }
  1534.         nextchar = arg[len];
  1535.         arg[len] = NUL;                /* put NUL after name */
  1536.         opt_idx = findoption(arg);
  1537.         arg[len] = nextchar;            /* restore nextchar */
  1538.         key = 0;
  1539.         if (opt_idx == -1)
  1540.             key = find_key_option(arg);
  1541.         }
  1542.  
  1543.         if (opt_idx == -1 && key == 0)    /* found a mismatch: skip */
  1544.         {
  1545.         errmsg = (char_u *)"Unknown option";
  1546.         goto skip;
  1547.         }
  1548.  
  1549.         if (opt_idx >= 0)
  1550.         {
  1551.         if (options[opt_idx].var == NULL)   /* hidden option: skip */
  1552.             goto skip;
  1553.  
  1554.         flags = options[opt_idx].flags;
  1555.         varp = get_varp(&(options[opt_idx]));
  1556.         }
  1557.         else
  1558.         flags = P_STRING;
  1559.  
  1560.         /* remember character after option name */
  1561.         afterchar = nextchar;
  1562.  
  1563.         /* skip white space, allow ":set ai  ?" */
  1564.         while (vim_iswhite(nextchar))
  1565.         nextchar = arg[++len];
  1566.  
  1567.         if (vim_strchr((char_u *)"?=:!&", nextchar) != NULL)
  1568.         {
  1569.         arg += len;
  1570.         len = 0;
  1571.         }
  1572.  
  1573.         /*
  1574.          * allow '=' and ':' as MSDOS command.com allows only one
  1575.          * '=' character per "set" command line. grrr. (jw)
  1576.          */
  1577.         if (nextchar == '?' || (prefix == 1 && vim_strchr((char_u *)"=:&",
  1578.                       nextchar) == NULL && !(flags & P_BOOL)))
  1579.         {                        /* print value */
  1580.         if (did_show)
  1581.             msg_putchar('\n');        /* cursor below last one */
  1582.         else
  1583.         {
  1584.             gotocmdline(TRUE);        /* cursor at status line */
  1585.             did_show = TRUE;        /* remember that we did a line */
  1586.         }
  1587.         if (opt_idx >= 0)
  1588.             showoneopt(&options[opt_idx]);
  1589.         else
  1590.         {
  1591.             char_u        name[2];
  1592.             char_u        *p;
  1593.  
  1594.             name[0] = KEY2TERMCAP0(key);
  1595.             name[1] = KEY2TERMCAP1(key);
  1596.             p = find_termcode(name);
  1597.             if (p == NULL)
  1598.             {
  1599.             errmsg = (char_u *)"Unknown option";
  1600.             goto skip;
  1601.             }
  1602.             else
  1603.             (void)show_one_termcode(name, p, TRUE);
  1604.         }
  1605.         if (nextchar != '?' && nextchar != NUL &&
  1606.                               !vim_iswhite(afterchar))
  1607.             errmsg = e_trailing;
  1608.         }
  1609.         else
  1610.         {
  1611.         if (flags & P_BOOL)            /* boolean */
  1612.         {
  1613.             if (nextchar == '=' || nextchar == ':')
  1614.             {
  1615.             errmsg = e_invarg;
  1616.             goto skip;
  1617.             }
  1618.  
  1619.             /*
  1620.              * ":set opt!" or ":set invopt": invert
  1621.              * ":set opt&": reset to default value
  1622.              * ":set opt" or ":set noopt": set or reset
  1623.              */
  1624.             if (prefix == 2 || nextchar == '!')
  1625.             value = *(int *)(varp) ^ 1;
  1626.             else if (nextchar == '&')
  1627.             {
  1628.             /* Use a trick here to get the default value, without
  1629.              * setting the actual value yet. */
  1630.             i = *(int *)varp;
  1631.             set_option_default(opt_idx, FALSE);
  1632.             value = *(int *)varp;
  1633.             *(int *)varp = i;
  1634.             }
  1635.             else
  1636.             value = prefix;
  1637.  
  1638.             errmsg = set_bool_option(opt_idx, varp, (int)value);
  1639.         }
  1640.         else                    /* numeric or string */
  1641.         {
  1642.             if (vim_strchr((char_u *)"=:&", nextchar) == NULL
  1643.                                    || prefix != 1)
  1644.             {
  1645.             errmsg = e_invarg;
  1646.             goto skip;
  1647.             }
  1648.  
  1649.             if (flags & P_NUM)            /* numeric */
  1650.             {
  1651.             /*
  1652.              * Different ways to set a number option:
  1653.              * &        set to default value
  1654.              * <xx>        accept special key codes for 'wildchar'
  1655.              * c        accept any non-digit for 'wildchar'
  1656.              * [-]0-9   set number
  1657.              * other    error
  1658.              */
  1659.             arg += len + 1;
  1660.             if (nextchar == '&')
  1661.             {
  1662.                 long    temp;
  1663.  
  1664.                 /* Use a trick here to get the default value,
  1665.                  * without setting the actual value yet. */
  1666.                 temp = *(long *)varp;
  1667.                 set_option_default(opt_idx, FALSE);
  1668.                 value = *(long *)varp;
  1669.                 *(long *)varp = temp;
  1670.             }
  1671.             else if (  (long *)varp == &p_wc
  1672.                 && (*arg == '<'
  1673.                     || *arg == '^'
  1674.                     || ((!arg[1] || vim_iswhite(arg[1]))
  1675.                     && !isdigit(*arg))))
  1676.             {
  1677.                 if (*arg == '<')
  1678.                 value = find_key_option(arg + 1);
  1679.                 else if (*arg == '^')
  1680.                 value = arg[1] ^ 0x40;
  1681.                 else
  1682.                 value = *arg;
  1683.                 if (value == 0)
  1684.                 {
  1685.                 errmsg = e_invarg;
  1686.                 goto skip;
  1687.                 }
  1688.             }
  1689.                 /* allow negative numbers (for 'undolevels') */
  1690.             else if (*arg == '-' || isdigit(*arg))
  1691.             {
  1692.                 i = 0;
  1693.                 if (*arg == '-')
  1694.                 i = 1;
  1695. #ifdef HAVE_STRTOL
  1696.                 value = strtol((char *)arg, NULL, 0);
  1697.                 if (arg[i] == '0' && TO_LOWER(arg[i + 1]) == 'x')
  1698.                 i += 2;
  1699. #else
  1700.                 value = atol((char *)arg);
  1701. #endif
  1702.                 while (isdigit(arg[i]))
  1703.                 ++i;
  1704.                 if (arg[i] != NUL && !vim_iswhite(arg[i]))
  1705.                 {
  1706.                 errmsg = e_invarg;
  1707.                 goto skip;
  1708.                 }
  1709.             }
  1710.             else
  1711.             {
  1712.                 errmsg = (char_u *)"Number required after =";
  1713.                 goto skip;
  1714.             }
  1715.  
  1716.             errmsg = set_num_option(opt_idx, varp, value, errbuf);
  1717.             }
  1718.             else if (opt_idx >= 0)            /* string */
  1719.             {
  1720.             char_u        *save_arg = NULL;
  1721.             char_u        *s;
  1722.             char_u        *oldval;    /* previous value if *varp */
  1723.             int        new_value_alloced;    /* new string option
  1724.                                was allocated */
  1725.  
  1726.             /* The old value is kept until we are sure that the new
  1727.              * value is valid.  set_option_default() is therefore
  1728.              * called with FALSE
  1729.              */
  1730.             oldval = *(char_u **)(varp);
  1731.             if (nextchar == '&')        /* set to default val */
  1732.             {
  1733.                 set_option_default(opt_idx, FALSE);
  1734.                 new_value_alloced =
  1735.                      (options[opt_idx].flags & P_ALLOCED);
  1736.             }
  1737.             else
  1738.             {
  1739.                 arg += len + 1; /* jump to after the '=' or ':' */
  1740.  
  1741.                 /*
  1742.                  * Convert 'whichwrap' number to string, for
  1743.                  * backwards compatibility with Vim 3.0.
  1744.                  * Misuse errbuf[] for the resulting string.
  1745.                  */
  1746.                 if (varp == (char_u *)&p_ww && isdigit(*arg))
  1747.                 {
  1748.                 *errbuf = NUL;
  1749.                 i = getdigits(&arg);
  1750.                 if (i & 1)
  1751.                     STRCAT(errbuf, "b,");
  1752.                 if (i & 2)
  1753.                     STRCAT(errbuf, "s,");
  1754.                 if (i & 4)
  1755.                     STRCAT(errbuf, "h,l,");
  1756.                 if (i & 8)
  1757.                     STRCAT(errbuf, "<,>,");
  1758.                 if (i & 16)
  1759.                     STRCAT(errbuf, "[,],");
  1760.                 if (*errbuf != NUL)    /* remove trailing , */
  1761.                     errbuf[STRLEN(errbuf) - 1] = NUL;
  1762.                 save_arg = arg;
  1763.                 arg = errbuf;
  1764.                 }
  1765.                 /*
  1766.                  * Remove '>' before 'dir' and 'bdir', for
  1767.                  * backwards compatibility with version 3.0
  1768.                  */
  1769.                 else if (  *arg == '>'
  1770.                     && (varp == (char_u *)&p_dir
  1771.                         || varp == (char_u *)&p_bdir))
  1772.                 {
  1773.                 ++arg;
  1774.                 }
  1775.  
  1776.                 /*
  1777.                  * Copy the new string into allocated memory.
  1778.                  * Can't use set_string_option_direct(), because
  1779.                  * we need to remove the backslashes.
  1780.                  */
  1781.                         /* may get a bit too much */
  1782.                 s = alloc((unsigned)(STRLEN(arg) + 1));
  1783.                 if (s == NULL)  /* out of memory, don't change */
  1784.                 break;
  1785.                 *(char_u **)(varp) = s;
  1786.  
  1787.                 /*
  1788.                  * Copy the string, skip over escaped chars.
  1789.                  * For MS-DOS and WIN32 backslashes before normal
  1790.                  * file name characters are not removed.
  1791.                  */
  1792.                 while (*arg && !vim_iswhite(*arg))
  1793.                 {
  1794.                 if (*arg == '\\' && arg[1] != NUL
  1795. #ifdef BACKSLASH_IN_FILENAME
  1796.                     && !((flags & P_EXPAND)
  1797.                         && vim_isfilec(arg[1])
  1798.                         && arg[1] != '\\')
  1799. #endif
  1800.                                     )
  1801.                     ++arg;
  1802.                 *s++ = *arg++;
  1803.                 }
  1804.                 *s = NUL;
  1805.  
  1806.                 if (save_arg != NULL)   /* number for 'whichwrap' */
  1807.                 arg = save_arg;
  1808.                 new_value_alloced = TRUE;
  1809.             }
  1810.  
  1811.             /* expand environment variables and ~ */
  1812.             s = option_expand(opt_idx);
  1813.             if (s != NULL)
  1814.             {
  1815.                 if (new_value_alloced)
  1816.                 vim_free(*(char_u **)(varp));
  1817.                 *(char_u **)(varp) = s;
  1818.                 new_value_alloced = TRUE;
  1819.             }
  1820.  
  1821.             errmsg = did_set_string_option(opt_idx, (char_u **)varp,
  1822.                        new_value_alloced, oldval, errbuf);
  1823.             /*
  1824.              * If error detected, print the error message.
  1825.              */
  1826.             if (errmsg != NULL)
  1827.                 goto skip;
  1828.             }
  1829.             else        /* key code option */
  1830.             {
  1831.             char_u        name[2];
  1832.             char_u        *p;
  1833.  
  1834.             name[0] = KEY2TERMCAP0(key);
  1835.             name[1] = KEY2TERMCAP1(key);
  1836.             if (nextchar == '&')
  1837.             {
  1838.                 if (add_termcap_entry(name, TRUE) == FAIL)
  1839.                 errmsg = (char_u *)"Not found in termcap";
  1840.             }
  1841.             else
  1842.             {
  1843.                 arg += len + 1; /* jump to after the '=' or ':' */
  1844.                 for(p = arg; *p && !vim_iswhite(*p); ++p)
  1845.                 {
  1846.                 if (*p == '\\' && *(p + 1))
  1847.                     ++p;
  1848.                 }
  1849.                 nextchar = *p;
  1850.                 *p = NUL;
  1851.                 add_termcode(name, arg);
  1852.                 *p = nextchar;
  1853.             }
  1854.             if (full_screen)
  1855.                 ttest(FALSE);
  1856.             redraw_all_later(CLEAR);
  1857.             }
  1858.         }
  1859.         if (opt_idx >= 0)
  1860.             options[opt_idx].flags |= P_WAS_SET;
  1861.         }
  1862.  
  1863. skip:
  1864.         /*
  1865.          * Advance to next argument.
  1866.          * - skip until a blank found, taking care of backslashes
  1867.          * - skip blanks
  1868.          */
  1869.         while (*arg != NUL && !vim_iswhite(*arg))
  1870.         if (*arg++ == '\\' && *arg != NUL)
  1871.             ++arg;
  1872.     }
  1873.     arg = skipwhite(arg);
  1874.  
  1875.     if (errmsg)
  1876.     {
  1877.         ++no_wait_return;    /* wait_return done below */
  1878.         emsg(errmsg);    /* show error highlighted */
  1879.         MSG_PUTS(": ");
  1880.                 /* show argument normal */
  1881.         while (startarg < arg)
  1882.         msg_puts(transchar(*startarg++));
  1883.         msg_end();        /* check for scrolling */
  1884.         --no_wait_return;
  1885.  
  1886.         ++errcnt;        /* count number of errors */
  1887.         did_show = TRUE;    /* error message counts as show */
  1888.         if (sourcing_name != NULL)
  1889.         break;
  1890.     }
  1891.     }
  1892.  
  1893.     return (errcnt == 0 ? OK : FAIL);
  1894. }
  1895.  
  1896.     static void
  1897. illegal_char(errbuf, c)
  1898.     char_u    *errbuf;
  1899.     int        c;
  1900. {
  1901.     sprintf((char *)errbuf, "Illegal character <%s>", (char *)transchar(c));
  1902. }
  1903.  
  1904. /*
  1905.  * When changing 'title', 'titlestring', 'icon' or 'iconstring', call
  1906.  * maketitle() to create and display it.
  1907.  * When switching the title or icon off, call mch_restore_title() to get
  1908.  * the old value back.
  1909.  */
  1910.     static void
  1911. did_set_title(icon)
  1912.     int        icon;        /* Did set icon instead of title */
  1913. {
  1914.     if (!starting
  1915. #ifdef USE_GUI
  1916.         && !gui.starting
  1917. #endif
  1918.                 )
  1919.     {
  1920.     maketitle();
  1921.     if (icon)
  1922.     {
  1923.         if (!p_icon && *p_iconstring == NUL)
  1924.         mch_restore_title(2);
  1925.     }
  1926.     else
  1927.     {
  1928.         if (!p_title && *p_titlestring == NUL)
  1929.         mch_restore_title(1);
  1930.     }
  1931.     }
  1932. }
  1933.  
  1934. /*
  1935.  * set_options_bin -  called when 'bin' changes value.
  1936.  */
  1937.     void
  1938. set_options_bin(oldval, newval)
  1939.     int        oldval;
  1940.     int        newval;
  1941. {
  1942.     /*
  1943.      * The option values that are changed when 'bin' changes are
  1944.      * copied when 'bin is set and restored when 'bin' is reset.
  1945.      */
  1946.     if (newval)
  1947.     {
  1948.     if (!oldval)        /* switched on */
  1949.     {
  1950.         curbuf->b_p_tw_nobin = curbuf->b_p_tw;
  1951.         curbuf->b_p_wm_nobin = curbuf->b_p_wm;
  1952.         curbuf->b_p_ml_nobin = curbuf->b_p_ml;
  1953.         curbuf->b_p_et_nobin = curbuf->b_p_et;
  1954.     }
  1955.  
  1956.     curbuf->b_p_tw = 0;    /* no automatic line wrap */
  1957.     curbuf->b_p_wm = 0;    /* no automatic line wrap */
  1958.     curbuf->b_p_ml = 0;    /* no modelines */
  1959.     curbuf->b_p_et = 0;    /* no expandtab */
  1960.     }
  1961.     else if (oldval)        /* switched off */
  1962.     {
  1963.     curbuf->b_p_tw = curbuf->b_p_tw_nobin;
  1964.     curbuf->b_p_wm = curbuf->b_p_wm_nobin;
  1965.     curbuf->b_p_ml = curbuf->b_p_ml_nobin;
  1966.     curbuf->b_p_et = curbuf->b_p_et_nobin;
  1967.     }
  1968. }
  1969.  
  1970. #ifdef VIMINFO
  1971. /*
  1972.  * Find the parameter represented by the given character (eg ', :, ", or /),
  1973.  * and return its associated value in the 'viminfo' string.
  1974.  * Only works for number parameters, not for 'r' or 'n'.
  1975.  * If the parameter is not specified in the string, return -1.
  1976.  */
  1977.     int
  1978. get_viminfo_parameter(type)
  1979.     int        type;
  1980. {
  1981.     char_u  *p;
  1982.  
  1983.     p = find_viminfo_parameter(type);
  1984.     if (p != NULL && isdigit(*p))
  1985.     return atoi((char *)p);
  1986.     return -1;
  1987. }
  1988.  
  1989. /*
  1990.  * Find the parameter represented by the given character (eg ', :, ", or /) in
  1991.  * the 'viminfo' option and return a pointer to the string after it.
  1992.  * Return NULL if the parameter is not specified in the string.
  1993.  */
  1994.     char_u *
  1995. find_viminfo_parameter(type)
  1996.     int        type;
  1997. {
  1998.     char_u  *p;
  1999.  
  2000.     for (p = p_viminfo; *p; ++p)
  2001.     {
  2002.     if (*p == type)
  2003.         return p + 1;
  2004.     if (*p == 'n')            /* 'n' is always the last one */
  2005.         break;
  2006.     p = vim_strchr(p, ',');        /* skip until next ',' */
  2007.     if (p == NULL)            /* hit the end without finding parameter */
  2008.         break;
  2009.     }
  2010.     return NULL;
  2011. }
  2012. #endif
  2013.  
  2014. /*
  2015.  * Expand environment variables for some string options.
  2016.  * These string options cannot be indirect!
  2017.  * Return pointer to allocated memory, or NULL when not expanded.
  2018.  */
  2019.     static char_u *
  2020. option_expand(opt_idx)
  2021.     int        opt_idx;
  2022. {
  2023.     char_u    *p;
  2024.  
  2025.     /* if option doesn't need expansion or is hidden: nothing to do */
  2026.     if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL)
  2027.     return NULL;
  2028.  
  2029.     p = *(char_u **)(options[opt_idx].var);
  2030.  
  2031.     /*
  2032.      * Expanding this with NameBuff, expand_env() must not be passed IObuff.
  2033.      */
  2034.     expand_env(p, NameBuff, MAXPATHL);
  2035.     if (STRCMP(NameBuff, p) == 0)   /* they are the same */
  2036.     return NULL;
  2037.  
  2038.     return vim_strsave(NameBuff);
  2039. }
  2040.  
  2041. /*
  2042.  * Check for string options that are NULL (normally only termcap options).
  2043.  */
  2044.     void
  2045. check_options()
  2046. {
  2047.     int        opt_idx;
  2048.     char_u  **p;
  2049.  
  2050.     for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
  2051.     if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL)
  2052.     {
  2053.         p = (char_u **)get_varp(&(options[opt_idx]));
  2054.         if (*p == NULL)
  2055.         *p = empty_option;
  2056.     }
  2057. }
  2058.  
  2059. /*
  2060.  * Check string options in a buffer for NULL value.
  2061.  */
  2062.     void
  2063. check_buf_options(buf)
  2064.     BUF        *buf;
  2065. {
  2066.     if (buf->b_p_ff == NULL)
  2067.     buf->b_p_ff = empty_option;
  2068.     if (buf->b_p_fo == NULL)
  2069.     buf->b_p_fo = empty_option;
  2070.     if (buf->b_p_isk == NULL)
  2071.     buf->b_p_isk = empty_option;
  2072.     if (buf->b_p_com == NULL)
  2073.     buf->b_p_com = empty_option;
  2074.     if (buf->b_p_nf == NULL)
  2075.     buf->b_p_nf = empty_option;
  2076. #ifdef CINDENT
  2077.     if (buf->b_p_cink == NULL)
  2078.     buf->b_p_cink = empty_option;
  2079.     if (buf->b_p_cino == NULL)
  2080.     buf->b_p_cino = empty_option;
  2081. #endif
  2082. #if defined(SMARTINDENT) || defined(CINDENT)
  2083.     if (buf->b_p_cinw == NULL)
  2084.     buf->b_p_cinw = empty_option;
  2085. #endif
  2086. #ifdef INSERT_EXPAND
  2087.     if (buf->b_p_cpt == NULL)
  2088.     buf->b_p_cpt = empty_option;
  2089. #endif
  2090. }
  2091.  
  2092. /*
  2093.  * Free the string allocated for an option.
  2094.  * Checks for the string being empty_option. This may happen if we're out of
  2095.  * memory, vim_strsave() returned NULL, which was replaced by empty_option by
  2096.  * check_options().
  2097.  * Does NOT check for P_ALLOCED flag!
  2098.  */
  2099.     void
  2100. free_string_option(p)
  2101.     char_u    *p;
  2102. {
  2103.     if (p != empty_option)
  2104.     vim_free(p);
  2105. }
  2106.  
  2107. /*
  2108.  * Set a string option to a new value (without checking the effect).
  2109.  * The string is copied into allocated memory.
  2110.  * If 'dofree' is set, the old value may be freed.
  2111.  * if (opt_idx == -1) name is used, otherwise opt_idx is used.
  2112.  */
  2113.     void
  2114. set_string_option_direct(name, opt_idx, val, dofree)
  2115.     char_u  *name;
  2116.     int        opt_idx;
  2117.     char_u  *val;
  2118.     int        dofree;
  2119. {
  2120.     char_u  *s;
  2121.     char_u  **varp;
  2122.  
  2123.     if (opt_idx == -1)        /* use name */
  2124.     {
  2125.     opt_idx = findoption(name);
  2126.     if (opt_idx == -1)    /* not found (should not happen) */
  2127.         return;
  2128.     }
  2129.  
  2130.     if (options[opt_idx].var == NULL)    /* can't set hidden option */
  2131.     return;
  2132.  
  2133.     s = vim_strsave(val);
  2134.     if (s != NULL)
  2135.     {
  2136.     varp = (char_u **)get_varp(&(options[opt_idx]));
  2137.     if (dofree && (options[opt_idx].flags & P_ALLOCED))
  2138.         free_string_option(*varp);
  2139.     *varp = s;
  2140.     options[opt_idx].flags |= P_ALLOCED;
  2141.     }
  2142. }
  2143.  
  2144. /*
  2145.  * Set a string option to a new value, and handle the effects.
  2146.  */
  2147.     static void
  2148. set_string_option(opt_idx, value)
  2149.     int        opt_idx;
  2150.     char_u  *value;
  2151. {
  2152.     char_u  *s;
  2153.     char_u  **varp;
  2154.     char_u  *oldval;
  2155.  
  2156.     if (options[opt_idx].var == NULL)    /* don't set hidden option */
  2157.     return;
  2158.  
  2159.     s = vim_strsave(value);
  2160.     if (s != NULL)
  2161.     {
  2162.     varp = (char_u **)get_varp(&(options[opt_idx]));
  2163.     oldval = *varp;
  2164.     *varp = s;
  2165.     (void)did_set_string_option(opt_idx, varp, TRUE, oldval, NULL);
  2166.     }
  2167. }
  2168.  
  2169. /*
  2170.  * Handle string options that need some action to perform when changed.
  2171.  * Returns NULL for success, or an error message for an error.
  2172.  */
  2173.     static char_u *
  2174. did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf)
  2175.     int        opt_idx;        /* index in options[] table */
  2176.     char_u    **varp;            /* pointer to the option variable */
  2177.     int        new_value_alloced;    /* new value was allocated */
  2178.     char_u    *oldval;        /* previous value of the option */
  2179.     char_u    *errbuf;        /* buffer for errors, or NULL */
  2180. {
  2181.     char_u    *errmsg = NULL;
  2182.     char_u    *s, *p;
  2183.     int        did_chartab = FALSE;
  2184.  
  2185.     /* 'term' */
  2186.     if (varp == &T_NAME)
  2187.     {
  2188.     if (T_NAME[0] == NUL)
  2189.         errmsg = (char_u *)"Cannot set 'term' to empty string";
  2190. #ifdef USE_GUI
  2191.     if (gui.in_use)
  2192.         errmsg = (char_u *)"Cannot change term in GUI";
  2193.     else if (term_is_gui(T_NAME))
  2194.         errmsg = (char_u *)"Use \":gui\" to start the GUI";
  2195. #endif
  2196.     else if (set_termname(T_NAME) == FAIL)
  2197.         errmsg = (char_u *)"Not found in termcap";
  2198.     else
  2199.     {
  2200.         /* Screen colors may have changed. */
  2201.         out_str(T_ME);
  2202.         update_screen(CLEAR);
  2203.     }
  2204.     }
  2205.  
  2206.     /* 'backupext' and 'patchmode' */
  2207.     else if ((varp == &p_bex || varp == &p_pm))
  2208.     {
  2209.     if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex,
  2210.              *p_pm == '.' ? p_pm + 1 : p_pm) == 0)
  2211.         errmsg = (char_u *)"'backupext' and 'patchmode' are equal";
  2212.     }
  2213.  
  2214.     /*
  2215.      * 'isident', 'iskeyword', 'isprint or 'isfname' option: refill chartab[]
  2216.      * If the new option is invalid, use old value.  'lisp' option: refill
  2217.      * chartab[] for '-' char
  2218.      */
  2219.     else if (  varp == &p_isi
  2220.         || varp == &(curbuf->b_p_isk)
  2221.         || varp == &p_isp
  2222.         || varp == &p_isf)
  2223.     {
  2224.     if (init_chartab() == FAIL)
  2225.     {
  2226.         did_chartab = TRUE;        /* need to restore it below */
  2227.         errmsg = e_invarg;        /* error in value */
  2228.     }
  2229.     }
  2230.  
  2231.     /* 'highlight' */
  2232.     else if (varp == &p_hl)
  2233.     {
  2234.     if (highlight_changed() == FAIL)
  2235.         errmsg = e_invarg;    /* invalid flags */
  2236.     }
  2237.  
  2238.     /* 'nrformats' */
  2239.     else if (varp == &(curbuf->b_p_nf))
  2240.     {
  2241.     if (check_opt_strings(curbuf->b_p_nf, p_nf_values, TRUE) != OK)
  2242.         errmsg = e_invarg;
  2243.     }
  2244.  
  2245.     /* 'background' */
  2246.     else if (varp == &p_bg)
  2247.     {
  2248.     if (check_opt_strings(p_bg, p_bg_values, FALSE) == OK)
  2249.     {
  2250.         if (full_screen)
  2251.         init_highlight(FALSE);
  2252.     }
  2253.     else
  2254.         errmsg = e_invarg;
  2255.     }
  2256.  
  2257. #ifdef AUTOCMD
  2258.     /* 'eventignore' */
  2259.     else if (varp == &p_ei)
  2260.     {
  2261.     if (check_ei() == FAIL)
  2262.         errmsg = e_invarg;
  2263.     }
  2264. #endif
  2265.  
  2266.     /* 'fileformat' */
  2267.     else if (varp == &(curbuf->b_p_ff))
  2268.     {
  2269.     if (check_opt_strings(curbuf->b_p_ff, p_ff_values, FALSE) != OK)
  2270.         errmsg = e_invarg;
  2271.     else
  2272.     {
  2273.         /* also change 'textmode' */
  2274.         if (get_fileformat(curbuf) == EOL_DOS)
  2275.         curbuf->b_p_tx = TRUE;
  2276.         else
  2277.         curbuf->b_p_tx = FALSE;
  2278.     }
  2279.     }
  2280.  
  2281.     /* 'fileformats' */
  2282.     else if (varp == &p_ffs)
  2283.     {
  2284.     if (check_opt_strings(p_ffs, p_ff_values, TRUE) != OK)
  2285.         errmsg = e_invarg;
  2286.     else
  2287.     {
  2288.         /* also change 'textauto' */
  2289.         if (*p_ffs == NUL)
  2290.         p_ta = FALSE;
  2291.         else
  2292.         p_ta = TRUE;
  2293.     }
  2294.     }
  2295.  
  2296.     /* 'comments' */
  2297.     else if (varp == &(curbuf->b_p_com))
  2298.     {
  2299.     for (s = curbuf->b_p_com; *s; )
  2300.     {
  2301.         while (*s && *s != ':')
  2302.         {
  2303.         if (vim_strchr((char_u *)COM_ALL, *s) == NULL)
  2304.         {
  2305.             errmsg = (char_u *)"Illegal flag";
  2306.             break;
  2307.         }
  2308.         ++s;
  2309.         }
  2310.         if (*s++ == NUL)
  2311.         errmsg = (char_u *)"Missing colon";
  2312.         else if (*s == ',' || *s == NUL)
  2313.         errmsg = (char_u *)"Zero length string";
  2314.         if (errmsg != NULL)
  2315.         break;
  2316.         while (*s && *s != ',')
  2317.         {
  2318.         if (*s == '\\' && s[1] != NUL)
  2319.             ++s;
  2320.         ++s;
  2321.         }
  2322.         s = skip_to_option_part(s);
  2323.     }
  2324.     }
  2325.  
  2326. #ifdef VIMINFO
  2327.     /* 'viminfo' */
  2328.     else if (varp == &(p_viminfo))
  2329.     {
  2330.     for (s = p_viminfo; *s;)
  2331.     {
  2332.         /* Check it's a valid character */
  2333.         if (vim_strchr((char_u *)"\"'%frn:/", *s) == NULL)
  2334.         {
  2335.         if (errbuf != NULL)
  2336.         {
  2337.             illegal_char(errbuf, *s);
  2338.             errmsg = errbuf;
  2339.         }
  2340.         else
  2341.             errmsg = (char_u *)"";
  2342.         break;
  2343.         }
  2344.         if (*s == 'n')    /* name is always last one */
  2345.         {
  2346.         break;
  2347.         }
  2348.         else if (*s == 'r') /* skip until next ',' */
  2349.         {
  2350.         while (*++s && *s != ',')
  2351.             ;
  2352.         }
  2353.         else if (*s == '%') /* no extra chars */
  2354.         ++s;
  2355.         else            /* must have a number */
  2356.         {
  2357.         while (isdigit(*++s))
  2358.             ;
  2359.  
  2360.         if (!isdigit(*(s - 1)))
  2361.         {
  2362.             if (errbuf != NULL)
  2363.             {
  2364.             sprintf((char *)errbuf, "Missing number after <%s>",
  2365.                              transchar(*(s - 1)));
  2366.             errmsg = errbuf;
  2367.             }
  2368.             else
  2369.             errmsg = (char_u *)"";
  2370.             break;
  2371.         }
  2372.         }
  2373.         s = skip_to_option_part(s);
  2374.     }
  2375.     if (*p_viminfo && errmsg == NULL && get_viminfo_parameter('\'') < 0)
  2376.         errmsg = (char_u *)"Must specify a ' value";
  2377.     }
  2378. #endif /* VIMINFO */
  2379.  
  2380.     /* terminal options */
  2381.     else if (istermoption(&options[opt_idx]) && full_screen)
  2382.     {
  2383.     /* ":set t_Co=0" does ":set t_Co=" */
  2384.     if (varp == &T_CCO && atoi((char *)T_CCO) == 0)
  2385.     {
  2386.         if (new_value_alloced)
  2387.         vim_free(T_CCO);
  2388.         T_CCO = empty_option;
  2389.     }
  2390.     ttest(FALSE);
  2391.     if (varp == &T_ME)
  2392.     {
  2393.         out_str(T_ME);
  2394.         update_screen(CLEAR);
  2395.     }
  2396.     }
  2397.  
  2398.     /* 'showbreak' */
  2399.     else if (varp == &p_sbr)
  2400.     {
  2401.     for (s = p_sbr; *s; ++s)
  2402.         if (charsize(*s) != 1)
  2403.         errmsg = (char_u *)"contains unprintable character";
  2404.     }
  2405.  
  2406. #ifdef USE_GUI
  2407.     /* 'guifont' */
  2408.     else if (varp == &p_guifont)
  2409.     gui_init_font(p_guifont);
  2410.  
  2411.     /* 'guicursor' */
  2412.     else if (varp == &p_guicursor)
  2413.     errmsg = parse_guicursor();
  2414. #endif
  2415.  
  2416. #ifdef HAVE_LANGMAP
  2417.     /* 'langmap' */
  2418.     else if (varp == &p_langmap)
  2419.     langmap_set();
  2420. #endif
  2421.  
  2422.     /* 'breakat' */
  2423.     else if (varp == &p_breakat)
  2424.     fill_breakat_flags();
  2425.  
  2426.     /* 'titlestring' and 'iconstring' */
  2427.     else if (varp == &p_titlestring)
  2428.     did_set_title(FALSE);
  2429.     else if (varp == &p_iconstring)
  2430.     did_set_title(TRUE);
  2431.  
  2432. #ifdef USE_GUI
  2433.     /* 'guioptions' */
  2434.     else if (varp == &p_guioptions)
  2435.     gui_init_which_components(oldval);
  2436. #endif
  2437.  
  2438.     /* Options that are a list of flags. */
  2439.     else
  2440.     {
  2441.     p = NULL;
  2442.     if (varp == &p_ww)
  2443.         p = (char_u *)WW_ALL;
  2444.     if (varp == &p_shm)
  2445.         p = (char_u *)SHM_ALL;
  2446.     else if (varp == &(p_cpo))
  2447.         p = (char_u *)CPO_ALL;
  2448.     else if (varp == &(curbuf->b_p_fo))
  2449.         p = (char_u *)FO_ALL;
  2450.     else if (varp == &p_mouse)
  2451.     {
  2452. #ifdef USE_MOUSE
  2453.         p = (char_u *)MOUSE_ALL;
  2454. #else
  2455.         if (*p_mouse != NUL)
  2456.         errmsg = (char_u *)"No mouse support";
  2457. #endif
  2458.     }
  2459. #if defined(USE_GUI) || defined(USE_CLIPBOARD)
  2460.     else if (varp == &p_guioptions)
  2461.         p = (char_u *)GO_ALL;
  2462. #endif
  2463.     if (p != NULL)
  2464.     {
  2465.         for (s = *varp; *s; ++s)
  2466.         if (vim_strchr(p, *s) == NULL)
  2467.         {
  2468.             if (errbuf != NULL)
  2469.             {
  2470.             illegal_char(errbuf, *s);
  2471.             errmsg = errbuf;
  2472.             }
  2473.             else
  2474.             errmsg = (char_u *)"";
  2475.             break;
  2476.         }
  2477.     }
  2478.     }
  2479.  
  2480.     /*
  2481.      * If error detected, restore the previous value.
  2482.      */
  2483.     if (errmsg != NULL)
  2484.     {
  2485.     if (new_value_alloced)
  2486.         vim_free(*varp);
  2487.     *varp = oldval;
  2488.     /*
  2489.      * When resetting some values, need to act on it.
  2490.      */
  2491.     if (did_chartab)
  2492.         (void)init_chartab();
  2493.     if (varp == &p_hl)
  2494.         (void)highlight_changed();
  2495.     }
  2496.     else
  2497.     {
  2498.     /*
  2499.      * Free string options that are in allocated memory.
  2500.      */
  2501.     if (options[opt_idx].flags & P_ALLOCED)
  2502.         free_string_option(oldval);
  2503.     if (new_value_alloced)
  2504.         options[opt_idx].flags |= P_ALLOCED;
  2505.     else
  2506.         options[opt_idx].flags &= ~P_ALLOCED;
  2507.     }
  2508.  
  2509. #ifdef USE_MOUSE
  2510.     if (varp == &p_mouse)
  2511.     {
  2512.     if (*p_mouse == NUL)
  2513.         mch_setmouse(FALSE);    /* switch mouse off */
  2514.     else
  2515.         setmouse();            /* in case 'mouse' changed */
  2516.     }
  2517. #endif
  2518.  
  2519.     curwin->w_set_curswant = TRUE;  /* in case 'showbreak' changed */
  2520.     check_redraw(options[opt_idx].flags);
  2521.  
  2522.     return errmsg;
  2523. }
  2524.  
  2525. /*
  2526.  * Set the value of a boolean option, and take care of side effects.
  2527.  * Returns NULL for success, or an error message for an error.
  2528.  */
  2529.     static char_u *
  2530. set_bool_option(opt_idx, varp, value)
  2531.     int        opt_idx;            /* index in options[] table */
  2532.     char_u  *varp;            /* pointer to the option variable */
  2533.     int        value;            /* new value */
  2534. {
  2535.     int        old_p_bin = curbuf->b_p_bin;    /* remember old 'bin' option */
  2536.     int        old_p_ea = p_ea;            /* remember old 'equalalways' */
  2537.     int        old_p_wiv = p_wiv;            /* remember old 'weirdinvert' */
  2538. #ifdef FKMAP
  2539.     int        old_akm = p_altkeymap;        /* previous value if p_altkeymap*/
  2540. #endif
  2541.  
  2542.     /*
  2543.      * in secure mode, setting of the secure option is not
  2544.      * allowed
  2545.      */
  2546.     if (secure && (int *)varp == &p_secure)
  2547.     return (char_u *)"not allowed here";
  2548.  
  2549.     *(int *)varp = value;        /* set the new value */
  2550.  
  2551.     /* handle the setting of the compatible option */
  2552.     if ((int *)varp == &p_cp)
  2553.     {
  2554.     compatible_set();
  2555.     }
  2556.     /* when 'readonly' is reset, also reset readonlymode */
  2557.     else if ((int *)varp == &curbuf->b_p_ro && !curbuf->b_p_ro)
  2558.     readonlymode = FALSE;
  2559.  
  2560.     /* when 'bin' is set also set some other options */
  2561.     else if ((int *)varp == &curbuf->b_p_bin)
  2562.     {
  2563.     set_options_bin(old_p_bin, curbuf->b_p_bin);
  2564.     }
  2565.     /* when 'terse' is set change 'shortmess' */
  2566.     else if ((int *)varp == &p_terse)
  2567.     {
  2568.     char_u    *p;
  2569.  
  2570.     p = vim_strchr(p_shm, SHM_SEARCH);
  2571.  
  2572.     /* insert 's' in p_shm */
  2573.     if (p_terse && p == NULL)
  2574.     {
  2575.         STRCPY(IObuff, p_shm);
  2576.         STRCAT(IObuff, "s");
  2577.         set_string_option_direct((char_u *)"shm", -1, IObuff, TRUE);
  2578.     }
  2579.     /* remove 's' from p_shm */
  2580.     else if (!p_terse && p != NULL)
  2581.         vim_memmove(p, p + 1, STRLEN(p));
  2582.     }
  2583.     /* when 'paste' is set or reset also change other options */
  2584.     else if ((int *)varp == &p_paste)
  2585.     {
  2586.     paste_option_changed();
  2587.     }
  2588.     /* when 'ignorecase' is set or reset and 'hlsearch' is set, redraw */
  2589.     else if ((int *)varp == &p_ic && p_hls)
  2590.     {
  2591.     redraw_all_later(NOT_VALID);
  2592.     }
  2593.     /* when 'textmode' is set or reset also change 'fileformat' */
  2594.     else if ((int *)varp == &curbuf->b_p_tx)
  2595.     {
  2596.     set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX);
  2597.     }
  2598.     /* when 'textauto' is set or reset also change 'fileformats' */
  2599.     else if ((int *)varp == &p_ta)
  2600.     {
  2601.     set_string_option_direct((char_u *)"ffs", -1,
  2602.                   p_ta ? (char_u *)FFS_DFLT : (char_u *)"", TRUE);
  2603.     }
  2604.     /*
  2605.      * When 'lisp' option changes include/exclude '-' in
  2606.      * keyword characters.
  2607.      */
  2608. #ifdef LISPINDENT
  2609.     else if (varp == (char_u *)&(curbuf->b_p_lisp))
  2610.     init_chartab();        /* ignore errors */
  2611. #endif
  2612.     /* when 'title' changed, may need to change the title; same for 'icon' */
  2613.     else if ((int *)varp == &p_title)
  2614.     did_set_title(FALSE);
  2615.     else if ((int *)varp == &p_icon)
  2616.     did_set_title(TRUE);
  2617.     else if ((int *)varp == &curbuf->b_changed)
  2618.     {
  2619.     if (!value)
  2620.         curbuf->b_start_ffc = *curbuf->b_p_ff;    /* Buffer is unchanged */
  2621. #ifdef AUTOCMD
  2622.     modified_was_set = value;
  2623. #endif
  2624.     }
  2625.  
  2626.     if (p_ea && !old_p_ea)
  2627.     win_equal(curwin, FALSE);
  2628.  
  2629.     /*
  2630.      * When 'weirdinvert' changed, set/reset 't_xs'.
  2631.      * Then set 'weirdinvert' according to value of 't_xs'.
  2632.      */
  2633.     if (p_wiv && !old_p_wiv)
  2634.     T_XS = (char_u *)"y";
  2635.     else if (!p_wiv && old_p_wiv)
  2636.     T_XS = empty_option;
  2637.     p_wiv = (*T_XS != NUL);
  2638.  
  2639. #ifdef FKMAP
  2640.     /*
  2641.      * In case some second language keymapping options have changed, check
  2642.      * and correct the setting in a consistent way.
  2643.      */
  2644.     if (old_akm != p_altkeymap)
  2645.     {
  2646.     if (!p_altkeymap)
  2647.     {
  2648.         p_hkmap = p_fkmap;
  2649.         p_fkmap = 0;
  2650.         init_chartab();
  2651.     }
  2652.     else
  2653.     {
  2654.         p_fkmap = p_hkmap;
  2655.         p_hkmap = 0;
  2656.         init_chartab();
  2657.     }
  2658.     }
  2659.  
  2660.     /*
  2661.      * If hkmap set, reset Farsi keymapping.
  2662.      */
  2663.     if (p_hkmap && p_altkeymap)
  2664.     {
  2665.     p_altkeymap = 0;
  2666.     p_fkmap = 0;
  2667.     init_chartab();
  2668.     }
  2669.  
  2670.     /*
  2671.      * If fkmap set, reset Hebrew keymapping.
  2672.      */
  2673.     if (p_fkmap && !p_altkeymap)
  2674.     {
  2675.     p_altkeymap = 1;
  2676.     p_hkmap = 0;
  2677.     init_chartab();
  2678.     }
  2679. #endif
  2680.  
  2681.     options[opt_idx].flags |= P_WAS_SET;
  2682.  
  2683.     comp_col();                /* in case 'ruler' or 'showcmd' changed */
  2684.     curwin->w_set_curswant = TRUE;  /* in case 'list' changed */
  2685.     check_redraw(options[opt_idx].flags);
  2686.  
  2687.     return NULL;
  2688. }
  2689.  
  2690. /*
  2691.  * Set the value of a number option, and take care of side effects.
  2692.  * Returns NULL for success, or an error message for an error.
  2693.  */
  2694.     static char_u *
  2695. set_num_option(opt_idx, varp, value, errbuf)
  2696.     int        opt_idx;            /* index in options[] table */
  2697.     char_u  *varp;            /* pointer to the option variable */
  2698.     long    value;            /* new value */
  2699.     char_u  *errbuf;            /* buffer for error messages */
  2700. {
  2701.     char_u  *errmsg = NULL;
  2702.     long    old_Rows = Rows;        /* remember old Rows */
  2703.     long    old_Columns = Columns;    /* remember old Columns */
  2704.     long    old_p_ch = p_ch;        /* remember old command line height */
  2705.     long    old_p_uc = p_uc;        /* remember old 'updatecount' */
  2706.     long    old_titlelen = p_titlelen;    /* remember old 'titlelen' */
  2707.  
  2708.     *(long *)varp = value;
  2709.  
  2710.     /*
  2711.      * Number options that need some action when changed
  2712.      */
  2713.     if ((long *)varp == &p_wh || (long *)varp == &p_hh)
  2714.     {
  2715.     if (p_wh < 0)
  2716.     {
  2717.         errmsg = e_positive;
  2718.         p_wh = 0;
  2719.     }
  2720.     if (p_hh < 0)
  2721.     {
  2722.         errmsg = e_positive;
  2723.         p_hh = 0;
  2724.     }
  2725.  
  2726.     /* Change window height NOW */
  2727.     if (lastwin != firstwin)
  2728.     {
  2729.         if (p_wh)
  2730.         win_equal(curwin, TRUE);
  2731.         if (curbuf->b_help && curwin->w_height < p_hh)
  2732.         win_setheight((int)p_hh);
  2733.     }
  2734.     }
  2735.     /* (re)set last window status line */
  2736.     else if ((long *)varp == &p_ls)
  2737.     last_status();
  2738.  
  2739.     /*
  2740.      * Check the bounds for numeric options here
  2741.      */
  2742.     if (Rows < min_rows() && full_screen)
  2743.     {
  2744.     if (errbuf != NULL)
  2745.     {
  2746.         sprintf((char *)errbuf, "Need at least %d lines", min_rows());
  2747.         errmsg = errbuf;
  2748.     }
  2749.     Rows = min_rows();
  2750.     }
  2751.     if (Columns < MIN_COLUMNS && full_screen)
  2752.     {
  2753.     if (errbuf != NULL)
  2754.     {
  2755.         sprintf((char *)errbuf, "Need at least %d columns", MIN_COLUMNS);
  2756.         errmsg = errbuf;
  2757.     }
  2758.     Columns = MIN_COLUMNS;
  2759.     }
  2760.     /*
  2761.      * If the screenheight has been changed, assume it is the physical
  2762.      * screenheight.
  2763.      */
  2764.     if ((old_Rows != Rows || old_Columns != Columns) && full_screen)
  2765.     {
  2766.     ui_set_winsize();        /* try to change the window size */
  2767.     check_winsize();        /* in case 'columns' changed */
  2768. #ifdef MSDOS
  2769.     set_window();        /* active window may have changed */
  2770. #endif
  2771.     }
  2772.  
  2773.     if (curbuf->b_p_sts < 0)
  2774.     {
  2775.     errmsg = e_positive;
  2776.     curbuf->b_p_sts = 0;
  2777.     }
  2778.     if (curbuf->b_p_ts <= 0)
  2779.     {
  2780.     errmsg = e_positive;
  2781.     curbuf->b_p_ts = 8;
  2782.     }
  2783.     if (curbuf->b_p_tw < 0)
  2784.     {
  2785.     errmsg = e_positive;
  2786.     curbuf->b_p_tw = 0;
  2787.     }
  2788.     if (p_tm < 0)
  2789.     {
  2790.     errmsg = e_positive;
  2791.     p_tm = 0;
  2792.     }
  2793.     if (p_titlelen <= 0)
  2794.     {
  2795.     errmsg = e_positive;
  2796.     p_titlelen = 85;
  2797.     }
  2798.     if ((curwin->w_p_scroll <= 0 || curwin->w_p_scroll > curwin->w_height)
  2799.         && full_screen)
  2800.     {
  2801.     if (curwin->w_p_scroll != 0)
  2802.         errmsg = e_scroll;
  2803.     win_comp_scroll(curwin);
  2804.     }
  2805.     if (p_report < 0)
  2806.     {
  2807.     errmsg = e_positive;
  2808.     p_report = 1;
  2809.     }
  2810.     if ((p_sj < 0 || p_sj >= Rows) && full_screen)
  2811.     {
  2812.     if (Rows != old_Rows)        /* Rows changed, just adjust p_sj */
  2813.         p_sj = Rows / 2;
  2814.     else
  2815.     {
  2816.         errmsg = e_scroll;
  2817.         p_sj = 1;
  2818.     }
  2819.     }
  2820.     if (p_so < 0 && full_screen)
  2821.     {
  2822.     errmsg = e_scroll;
  2823.     p_so = 0;
  2824.     }
  2825.     if (p_uc < 0)
  2826.     {
  2827.     errmsg = e_positive;
  2828.     p_uc = 100;
  2829.     }
  2830.     if (p_ch < 1)
  2831.     {
  2832.     errmsg = e_positive;
  2833.     p_ch = 1;
  2834.     }
  2835.     if (p_ut < 0)
  2836.     {
  2837.     errmsg = e_positive;
  2838.     p_ut = 2000;
  2839.     }
  2840.     if (p_ss < 0)
  2841.     {
  2842.     errmsg = e_positive;
  2843.     p_ss = 0;
  2844.     }
  2845.  
  2846.     /* when 'updatecount' changes from zero to non-zero, open swap files */
  2847.     if (p_uc && !old_p_uc)
  2848.     ml_open_files();
  2849.  
  2850.     /* if p_ch changed value, change the command line height */
  2851.     if (p_ch != old_p_ch)
  2852.     command_height(old_p_ch);
  2853.  
  2854.     /* if 'titlelen' has changed, redraw the title */
  2855.     if (old_titlelen != p_titlelen && !starting)
  2856.     maketitle();
  2857.  
  2858.     options[opt_idx].flags |= P_WAS_SET;
  2859.  
  2860.     comp_col();                /* in case 'columns' or 'ls' changed */
  2861.     curwin->w_set_curswant = TRUE;  /* in case 'tabstop' changed */
  2862.     check_redraw(options[opt_idx].flags);
  2863.  
  2864.     return errmsg;
  2865. }
  2866.  
  2867. /*
  2868.  * Called after an option changed: check if something needs to be redrawn.
  2869.  */
  2870.     static void
  2871. check_redraw(flags)
  2872.     int        flags;
  2873. {
  2874.     if (flags & (P_RSTAT | P_RALL))    /* mark all status lines dirty */
  2875.     status_redraw_all();
  2876.  
  2877.     if (flags & (P_RBUF | P_RALL))
  2878.     {
  2879.     /* Update cursor position and botline (wrapping my have changed). */
  2880.     changed_line_abv_curs();
  2881.     invalidate_botline();
  2882.     update_topline();
  2883.     }
  2884.  
  2885.     if (flags & P_RBUF)
  2886.     redraw_curbuf_later(NOT_VALID);
  2887.     if (flags & P_RALL)
  2888.     redraw_all_later(NOT_VALID);
  2889. }
  2890.  
  2891. /*
  2892.  * Find index for option 'arg'.
  2893.  * Return -1 if not found.
  2894.  */
  2895.     static int
  2896. findoption(arg)
  2897.     char_u *arg;
  2898. {
  2899.     int            opt_idx;
  2900.     char        *s, *p;
  2901.     static short    quick_tab[27] = {0, 0};    /* quick access table */
  2902.     int            is_term_opt;
  2903.  
  2904.     /*
  2905.      * For first call: Initialize the quick-access table.
  2906.      * It contains the index for the first option that starts with a certain
  2907.      * letter.  There are 26 letters, plus the first "t_" option.
  2908.      */
  2909.     if (quick_tab[1] == 0)
  2910.     {
  2911.     p = options[0].fullname;
  2912.     for (opt_idx = 1; (s = options[opt_idx].fullname) != NULL; opt_idx++)
  2913.     {
  2914.         if (s[0] != p[0])
  2915.         {
  2916.         if (s[0] == 't' && s[1] == '_')
  2917.             quick_tab[26] = opt_idx;
  2918.         else
  2919.             quick_tab[s[0] - 'a'] = opt_idx;
  2920.         }
  2921.         p = s;
  2922.     }
  2923.     }
  2924.  
  2925.     /*
  2926.      * Check for name starting with an illegal character.
  2927.      */
  2928.     if (arg[0] < 'a' || arg[0] > 'z')
  2929.     return -1;
  2930.  
  2931.     is_term_opt = (arg[0] == 't' && arg[1] == '_');
  2932.     if (is_term_opt)
  2933.     opt_idx = quick_tab[26];
  2934.     else
  2935.     opt_idx = quick_tab[arg[0] - 'a'];
  2936.     for ( ; (s = options[opt_idx].fullname) != NULL; opt_idx++)
  2937.     {
  2938.     if (STRCMP(arg, s) == 0)            /* match full name */
  2939.         break;
  2940.     }
  2941.     if (s == NULL && !is_term_opt)
  2942.     {
  2943.     opt_idx = quick_tab[arg[0] - 'a'];
  2944.     for ( ; options[opt_idx].fullname != NULL; opt_idx++)
  2945.     {
  2946.         s = options[opt_idx].shortname;
  2947.         if (s != NULL && STRCMP(arg, s) == 0)   /* match short name */
  2948.         break;
  2949.         s = NULL;
  2950.     }
  2951.     }
  2952.     if (s == NULL)
  2953.     opt_idx = -1;
  2954.     return opt_idx;
  2955. }
  2956.  
  2957. /*
  2958.  * Get the value for an option.
  2959.  *
  2960.  * Returns:
  2961.  * Number or Toggle option: 1, *numval gets value.
  2962.  *         String option: 0, *stringval gets allocated string.
  2963.  *        unknown option: -1.
  2964.  */
  2965.     int
  2966. get_option_value(name, numval, stringval)
  2967.     char_u    *name;
  2968.     long    *numval;
  2969.     char_u    **stringval;        /* NULL when only checking existance */
  2970. {
  2971.     int        opt_idx;
  2972.     char_u  *varp;
  2973.  
  2974.     opt_idx = findoption(name);
  2975.     if (opt_idx < 0)            /* unknown option */
  2976.     return -1;
  2977.  
  2978.     varp = get_varp(&(options[opt_idx]));
  2979.     if (varp == NULL)            /* hidden option */
  2980.     return -1;
  2981.  
  2982.     if (options[opt_idx].flags & P_STRING)
  2983.     {
  2984.     if (stringval != NULL)
  2985.         *stringval = vim_strsave(*(char_u **)(varp));
  2986.     return 0;
  2987.     }
  2988.     if (options[opt_idx].flags & P_NUM)
  2989.     *numval = *(long *)varp;
  2990.     else
  2991.     *numval = *(int *)varp;
  2992.     return 1;
  2993. }
  2994.  
  2995. /*
  2996.  * Set the value of option "name".
  2997.  * Use "string" for string options, use "number" for other options.
  2998.  */
  2999.     void
  3000. set_option_value(name, number, string)
  3001.     char_u    *name;
  3002.     long    number;
  3003.     char_u    *string;
  3004. {
  3005.     int        opt_idx;
  3006.     char_u  *varp;
  3007.  
  3008.     opt_idx = findoption(name);
  3009.     if (opt_idx == -1)
  3010.     EMSG2("Unknown option: %s", name);
  3011.     else if (options[opt_idx].flags & P_STRING)
  3012.     set_string_option(opt_idx, string);
  3013.     else
  3014.     {
  3015.     varp = get_varp(&options[opt_idx]);
  3016.     if (varp != NULL)    /* hidden option is not changed */
  3017.     {
  3018.         if (options[opt_idx].flags & P_NUM)
  3019.         (void)set_num_option(opt_idx, varp, number, NULL);
  3020.         else
  3021.         (void)set_bool_option(opt_idx, varp, (int)number);
  3022.     }
  3023.     }
  3024. }
  3025.  
  3026. /*
  3027.  * Get the terminal code for a terminal option.
  3028.  * Returns NULL when not found.
  3029.  */
  3030.     char_u *
  3031. get_term_code(tname)
  3032.     char_u    *tname;
  3033. {
  3034.     int        opt_idx;
  3035.     char_u  *varp;
  3036.  
  3037.     if (tname[0] != 't' || tname[1] != '_' ||
  3038.         tname[2] == NUL || tname[3] == NUL)
  3039.     return NULL;
  3040.     if ((opt_idx = findoption(tname)) >= 0)
  3041.     {
  3042.     varp = get_varp(&(options[opt_idx]));
  3043.     if (varp != NULL)
  3044.         varp = *(char_u **)(varp);
  3045.     return varp;
  3046.     }
  3047.     return find_termcode(tname + 2);
  3048. }
  3049.  
  3050.     char_u *
  3051. get_highlight_default()
  3052. {
  3053.     int i;
  3054.  
  3055.     i = findoption((char_u *)"hl");
  3056.     if (i >= 0)
  3057.     return options[i].def_val[VI_DEFAULT];
  3058.     return (char_u *)NULL;
  3059. }
  3060.  
  3061. /*
  3062.  * Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
  3063.  */
  3064.     static int
  3065. find_key_option(arg)
  3066.     char_u *arg;
  3067. {
  3068.     int        key;
  3069.     int        modifiers;
  3070.  
  3071.     /*
  3072.      * Don't use get_special_key_code() for t_xx, we don't want it to call
  3073.      * add_termcap_entry().
  3074.      */
  3075.     if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
  3076.     key = TERMCAP2KEY(arg[2], arg[3]);
  3077.     else
  3078.     {
  3079.     --arg;                /* put arg at the '<' */
  3080.     key = find_special_key(&arg, &modifiers);
  3081.     if (modifiers)            /* can't handle modifiers here */
  3082.         key = 0;
  3083.     }
  3084.     return key;
  3085. }
  3086.  
  3087. /*
  3088.  * if 'all' == 0: show changed options
  3089.  * if 'all' == 1: show all normal options
  3090.  * if 'all' == 2: show all terminal options
  3091.  */
  3092.     static void
  3093. showoptions(all)
  3094.     int        all;
  3095. {
  3096.     struct vimoption   *p;
  3097.     int            col;
  3098.     int            isterm;
  3099.     char_u        *varp;
  3100.     struct vimoption    **items;
  3101.     int            item_count;
  3102.     int            run;
  3103.     int            row, rows;
  3104.     int            cols;
  3105.     int            i;
  3106.     int            len;
  3107.  
  3108. #define INC 20
  3109. #define GAP 3
  3110.  
  3111.     items = (struct vimoption **)alloc((unsigned)(sizeof(struct vimoption *) *
  3112.                                 PARAM_COUNT));
  3113.     if (items == NULL)
  3114.     return;
  3115.  
  3116.     /* Highlight title */
  3117.     if (all == 2)
  3118.     MSG_PUTS_TITLE("\n--- Terminal codes ---");
  3119.     else
  3120.     MSG_PUTS_TITLE("\n--- Options ---");
  3121.  
  3122.     /*
  3123.      * do the loop two times:
  3124.      * 1. display the short items
  3125.      * 2. display the long items (only strings and numbers)
  3126.      */
  3127.     for (run = 1; run <= 2 && !got_int; ++run)
  3128.     {
  3129.     /*
  3130.      * collect the items in items[]
  3131.      */
  3132.     item_count = 0;
  3133.     for (p = &options[0]; p->fullname != NULL; p++)
  3134.     {
  3135.         isterm = istermoption(p);
  3136.         varp = get_varp(p);
  3137.         if (varp != NULL && (
  3138.         (all == 2 && isterm) ||
  3139.         (all == 1 && !isterm) ||
  3140.         (all == 0 && option_not_default(p))))
  3141.         {
  3142.         if (p->flags & P_BOOL)
  3143.             len = 1;        /* a toggle option fits always */
  3144.         else
  3145.         {
  3146.             option_value2string(p);
  3147.             len = STRLEN(p->fullname) + vim_strsize(NameBuff) + 1;
  3148.         }
  3149.         if ((len <= INC - GAP && run == 1) ||
  3150.                         (len > INC - GAP && run == 2))
  3151.             items[item_count++] = p;
  3152.         }
  3153.     }
  3154.  
  3155.     /*
  3156.      * display the items
  3157.      */
  3158.     if (run == 1)
  3159.     {
  3160.         cols = (Columns + GAP - 3) / INC;
  3161.         if (cols == 0)
  3162.         cols = 1;
  3163.         rows = (item_count + cols - 1) / cols;
  3164.     }
  3165.     else    /* run == 2 */
  3166.         rows = item_count;
  3167.     for (row = 0; row < rows && !got_int; ++row)
  3168.     {
  3169.         msg_putchar('\n');            /* go to next line */
  3170.         if (got_int)            /* 'q' typed in more */
  3171.         break;
  3172.         col = 0;
  3173.         for (i = row; i < item_count; i += rows)
  3174.         {
  3175.         msg_col = col;            /* make columns */
  3176.         showoneopt(items[i]);
  3177.         col += INC;
  3178.         }
  3179.         out_flush();
  3180.         ui_breakcheck();
  3181.     }
  3182.     }
  3183.     vim_free(items);
  3184. }
  3185.  
  3186. /*
  3187.  * Return TRUE if option is different from the default value
  3188.  */
  3189.     static int
  3190. option_not_default(p)
  3191.     struct vimoption    *p;
  3192. {
  3193.     char_u  *varp;
  3194.     int        dvi;
  3195.  
  3196.     varp = get_varp(p);
  3197.     if (varp == NULL)
  3198.     return FALSE;    /* hidden option is never changed */
  3199.  
  3200.     if ((p->flags & P_VI_DEF) || p_cp)
  3201.     dvi = VI_DEFAULT;
  3202.     else
  3203.     dvi = VIM_DEFAULT;
  3204.     if (p->flags & P_NUM)
  3205.     return (*(long *)varp != (long)p->def_val[dvi]);
  3206.     if (p->flags & P_BOOL)
  3207.             /* the cast to long is required for Manx C */
  3208.     return (*(int *)varp != (int)(long)p->def_val[dvi]);
  3209.     /* P_STRING */
  3210.     return STRCMP(*(char_u **)varp, p->def_val[dvi]);
  3211. }
  3212.  
  3213. /*
  3214.  * showoneopt: show the value of one option
  3215.  * must not be called with a hidden option!
  3216.  */
  3217.     static void
  3218. showoneopt(p)
  3219.     struct vimoption *p;
  3220. {
  3221.     char_u        *varp;
  3222.  
  3223.     varp = get_varp(p);
  3224.  
  3225.     if ((p->flags & P_BOOL) && !*(int *)varp)
  3226.     MSG_PUTS("no");
  3227.     else
  3228.     MSG_PUTS("  ");
  3229.     MSG_PUTS(p->fullname);
  3230.     if (!(p->flags & P_BOOL))
  3231.     {
  3232.     msg_putchar('=');
  3233.     option_value2string(p);        /* put string of option value in NameBuff */
  3234.     msg_outtrans(NameBuff);
  3235.     }
  3236. }
  3237.  
  3238. /*
  3239.  * Write modified options as set command to a file.
  3240.  * Return FAIL on error, OK otherwise.
  3241.  */
  3242.     int
  3243. makeset(fd)
  3244.     FILE *fd;
  3245. {
  3246.     struct vimoption    *p;
  3247.     char_u        *s;
  3248.     int            e;
  3249.     char_u        *varp;
  3250.  
  3251.     /*
  3252.      * The options that don't have a default (terminal name, columns, lines)
  3253.      * are never written. Terminal options are also not written.
  3254.      */
  3255.     for (p = &options[0]; !istermoption(p); p++)
  3256.     if (!(p->flags & P_NO_MKRC) && !istermoption(p)
  3257.                            && (option_not_default(p)))
  3258.     {
  3259.         varp = get_varp(p);
  3260.         if (p->flags & P_BOOL)
  3261.         fprintf(fd, "set %s%s", *(int *)(varp) ? "" : "no",
  3262.                                  p->fullname);
  3263.         else if (p->flags & P_NUM)
  3264.         fprintf(fd, "set %s=%ld", p->fullname, *(long *)(varp));
  3265.         else    /* P_STRING */
  3266.         {
  3267.         fprintf(fd, "set %s=", p->fullname);
  3268.         s = *(char_u **)(varp);
  3269.         /* some characters have to be escaped with CTRL-V or
  3270.          * backslash */
  3271.         if (s != NULL && putescstr(fd, s, TRUE) == FAIL)
  3272.             return FAIL;
  3273.         }
  3274. #ifdef USE_CRNL
  3275.         putc('\r', fd);
  3276. #endif
  3277.         /*
  3278.          * Only check error for this putc, should catch at least
  3279.          * the "disk full" situation.
  3280.          */
  3281.         e = putc('\n', fd);
  3282.         if (e < 0)
  3283.         return FAIL;
  3284.     }
  3285.     return OK;
  3286. }
  3287.  
  3288. /*
  3289.  * Clear all the terminal options.
  3290.  * If the option has been allocated, free the memory.
  3291.  * Terminal options are never hidden or indirect.
  3292.  */
  3293.     void
  3294. clear_termoptions()
  3295. {
  3296.     struct vimoption   *p;
  3297.  
  3298.     /*
  3299.      * Reset a few things before clearing the old options. This may cause
  3300.      * outputting a few things that the terminal doesn't understand, but the
  3301.      * screen will be cleared later, so this is OK.
  3302.      */
  3303. #ifdef USE_MOUSE
  3304.     mch_setmouse(FALSE);        /* switch mouse off */
  3305. #endif
  3306.     mch_restore_title(3);        /* restore window titles */
  3307. #ifdef WIN32
  3308.     /*
  3309.      * Check if this is allowed now.
  3310.      */
  3311.     if (can_end_termcap_mode(FALSE) == TRUE)
  3312. #endif
  3313.     stoptermcap();            /* stop termcap mode */
  3314.  
  3315.     for (p = &options[0]; p->fullname != NULL; p++)
  3316.     if (istermoption(p))
  3317.     {
  3318.         if (p->flags & P_ALLOCED)
  3319.         free_string_option(*(char_u **)(p->var));
  3320.         if (p->flags & P_DEF_ALLOCED)
  3321.         free_string_option(p->def_val[VI_DEFAULT]);
  3322.         *(char_u **)(p->var) = empty_option;
  3323.         p->def_val[VI_DEFAULT] = empty_option;
  3324.         p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED);
  3325.     }
  3326.     clear_termcodes();
  3327. }
  3328.  
  3329. /*
  3330.  * Set the terminal option defaults to the current value.
  3331.  * Used after setting the terminal name.
  3332.  */
  3333.     void
  3334. set_term_defaults()
  3335. {
  3336.     struct vimoption   *p;
  3337.  
  3338.     for (p = &options[0]; p->fullname != NULL; p++)
  3339.     if (istermoption(p) && p->def_val[VI_DEFAULT] != *(char_u **)(p->var))
  3340.     {
  3341.         if (p->flags & P_DEF_ALLOCED)
  3342.         {
  3343.         free_string_option(p->def_val[VI_DEFAULT]);
  3344.         p->flags &= ~P_DEF_ALLOCED;
  3345.         }
  3346.         p->def_val[VI_DEFAULT] = *(char_u **)(p->var);
  3347.         if (p->flags & P_ALLOCED)
  3348.         {
  3349.         p->flags |= P_DEF_ALLOCED;
  3350.         p->flags &= ~P_ALLOCED;        /* don't free the value now */
  3351.         }
  3352.     }
  3353. }
  3354.  
  3355. /*
  3356.  * return TRUE if 'p' starts with 't_'
  3357.  */
  3358.     static int
  3359. istermoption(p)
  3360.     struct vimoption *p;
  3361. {
  3362.     return (p->fullname[0] == 't' && p->fullname[1] == '_');
  3363. }
  3364.  
  3365. /*
  3366.  * Compute columns for ruler and shown command. 'sc_col' is also used to
  3367.  * decide what the maximum length of a message on the status line can be.
  3368.  * If there is a status line for the last window, 'sc_col' is independent
  3369.  * of 'ru_col'.
  3370.  */
  3371.  
  3372. #define COL_RULER 17        /* columns needed by ruler */
  3373.  
  3374.     void
  3375. comp_col()
  3376. {
  3377.     int last_has_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
  3378.  
  3379.     sc_col = 0;
  3380.     ru_col = 0;
  3381.     if (p_ru)
  3382.     {
  3383.     ru_col = COL_RULER + 1;
  3384.     /* no last status line, adjust sc_col */
  3385.     if (!last_has_status)
  3386.         sc_col = ru_col;
  3387.     }
  3388.     if (p_sc)
  3389.     {
  3390.     sc_col += SHOWCMD_COLS;
  3391.     if (!p_ru || last_has_status)        /* no need for separating space */
  3392.         ++sc_col;
  3393.     }
  3394.     sc_col = Columns - sc_col;
  3395.     ru_col = Columns - ru_col;
  3396.     if (sc_col <= 0)        /* screen too narrow, will become a mess */
  3397.     sc_col = 1;
  3398.     if (ru_col <= 0)
  3399.     ru_col = 1;
  3400. }
  3401.  
  3402.     static char_u *
  3403. get_varp(p)
  3404.     struct vimoption    *p;
  3405. {
  3406.     if (!(p->flags & P_IND) || p->var == NULL)
  3407.     return p->var;
  3408.  
  3409.     switch ((long)(p->var))
  3410.     {
  3411.     case PV_LIST:    return (char_u *)&(curwin->w_p_list);
  3412.     case PV_NU:    return (char_u *)&(curwin->w_p_nu);
  3413. #ifdef RIGHTLEFT
  3414.     case PV_RL:    return (char_u *)&(curwin->w_p_rl);
  3415. #endif
  3416.     case PV_SCROLL:    return (char_u *)&(curwin->w_p_scroll);
  3417.     case PV_WRAP:    return (char_u *)&(curwin->w_p_wrap);
  3418.     case PV_LBR:    return (char_u *)&(curwin->w_p_lbr);
  3419.  
  3420.     case PV_AI:    return (char_u *)&(curbuf->b_p_ai);
  3421.     case PV_BIN:    return (char_u *)&(curbuf->b_p_bin);
  3422. #ifdef CINDENT
  3423.     case PV_CIN:    return (char_u *)&(curbuf->b_p_cin);
  3424.     case PV_CINK:    return (char_u *)&(curbuf->b_p_cink);
  3425.     case PV_CINO:    return (char_u *)&(curbuf->b_p_cino);
  3426. #endif
  3427. #if defined(SMARTINDENT) || defined(CINDENT)
  3428.     case PV_CINW:    return (char_u *)&(curbuf->b_p_cinw);
  3429. #endif
  3430.     case PV_COM:    return (char_u *)&(curbuf->b_p_com);
  3431. #ifdef INSERT_EXPAND
  3432.     case PV_CPT:    return (char_u *)&(curbuf->b_p_cpt);
  3433. #endif
  3434.     case PV_EOL:    return (char_u *)&(curbuf->b_p_eol);
  3435.     case PV_ET:    return (char_u *)&(curbuf->b_p_et);
  3436.     case PV_FF:    return (char_u *)&(curbuf->b_p_ff);
  3437.     case PV_FO:    return (char_u *)&(curbuf->b_p_fo);
  3438.     case PV_INF:    return (char_u *)&(curbuf->b_p_inf);
  3439.     case PV_ISK:    return (char_u *)&(curbuf->b_p_isk);
  3440.     case PV_LISP:    return (char_u *)&(curbuf->b_p_lisp);
  3441.     case PV_ML:    return (char_u *)&(curbuf->b_p_ml);
  3442.     case PV_MOD:    return (char_u *)&(curbuf->b_changed);
  3443.     case PV_NF:    return (char_u *)&(curbuf->b_p_nf);
  3444.     case PV_RO:    return (char_u *)&(curbuf->b_p_ro);
  3445. #ifdef SMARTINDENT
  3446.     case PV_SI:    return (char_u *)&(curbuf->b_p_si);
  3447. #endif
  3448. #ifndef SHORT_FNAME
  3449.     case PV_SN:    return (char_u *)&(curbuf->b_p_sn);
  3450. #endif
  3451.     case PV_STS:    return (char_u *)&(curbuf->b_p_sts);
  3452.     case PV_SW:    return (char_u *)&(curbuf->b_p_sw);
  3453.     case PV_TS:    return (char_u *)&(curbuf->b_p_ts);
  3454.     case PV_TW:    return (char_u *)&(curbuf->b_p_tw);
  3455.     case PV_TX:    return (char_u *)&(curbuf->b_p_tx);
  3456.     case PV_WM:    return (char_u *)&(curbuf->b_p_wm);
  3457.     default:    EMSG("get_varp ERROR");
  3458.     }
  3459.     /* always return a valid pointer to avoid a crash! */
  3460.     return (char_u *)&(curbuf->b_p_wm);
  3461. }
  3462.  
  3463. /*
  3464.  * Copy options from one window to another.
  3465.  * Used when creating a new window.
  3466.  * The 'scroll' option is not copied, because it depends on the window height.
  3467.  */
  3468.     void
  3469. win_copy_options(wp_from, wp_to)
  3470.     WIN        *wp_from;
  3471.     WIN        *wp_to;
  3472. {
  3473.     wp_to->w_p_list = wp_from->w_p_list;
  3474.     wp_to->w_p_nu = wp_from->w_p_nu;
  3475. #ifdef RIGHTLEFT
  3476.     wp_to->w_p_rl = wp_from->w_p_rl;
  3477. # ifdef FKMAP
  3478.     wp_to->w_p_pers = wp_from->w_p_pers;
  3479. # endif
  3480. #endif
  3481.     wp_to->w_p_wrap = wp_from->w_p_wrap;
  3482.     wp_to->w_p_lbr = wp_from->w_p_lbr;
  3483. }
  3484.  
  3485. /*
  3486.  * Copy options from one buffer to another.
  3487.  * Used when creating a new buffer and sometimes when entering a buffer.
  3488.  * flags:
  3489.  * BCO_ENTER    We will enter the bp_to buffer.
  3490.  * BCO_ALWAYS    Always copy the options, but only set b_p_initialized when
  3491.  *        appropriate.
  3492.  * BCO_NOHELP    Don't copy the help settings.
  3493.  */
  3494.     void
  3495. buf_copy_options(bp_from, bp_to, flags)
  3496.     BUF        *bp_from;
  3497.     BUF        *bp_to;
  3498.     int        flags;
  3499. {
  3500.     int        should_copy = TRUE;
  3501.     char_u  *save_p_isk = NULL;        /* init for GCC */
  3502.  
  3503.     /*
  3504.      * Don't do anything of the "to" buffer is invalid.
  3505.      */
  3506.     if (bp_to == NULL || !buf_valid(bp_to))
  3507.     return;
  3508.  
  3509.     /*
  3510.      * Only copy if the "from" buffer is valid and "to" and "from" are
  3511.      * different.
  3512.      */
  3513.     if (bp_from != NULL && buf_valid(bp_from) && bp_from != bp_to)
  3514.     {
  3515.     /*
  3516.      * Always copy when entering and 'cpo' contains 'S'.
  3517.      * Don't copy when already initialized.
  3518.      * Don't copy when 'cpo' contains 's' and not entering.
  3519.      * 'S'    BCO_ENTER  initialized    's'  should_copy
  3520.      * yes      yes           X     X    TRUE
  3521.      * yes      no          yes     X    FALSE
  3522.      * no       X          yes     X    FALSE
  3523.      *  X      no          no    yes    FALSE
  3524.      *  X      no          no    no    TRUE
  3525.      * no      yes          no     X    TRUE
  3526.      */
  3527.     if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !(flags & BCO_ENTER))
  3528.         && (bp_to->b_p_initialized
  3529.             || (!(flags & BCO_ENTER)
  3530.             && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
  3531.         should_copy = FALSE;
  3532.  
  3533.     if (should_copy || (flags & BCO_ALWAYS))
  3534.     {
  3535.         if ((flags & BCO_NOHELP))        /* don't free b_p_isk */
  3536.         {
  3537.         save_p_isk = bp_to->b_p_isk;
  3538.         bp_to->b_p_isk = NULL;
  3539.         }
  3540.         /*
  3541.          * Always free the allocated strings.
  3542.          * If not already initialized, set 'readonly' and copy 'fileformat'.
  3543.          */
  3544.         if (!bp_to->b_p_initialized)
  3545.         {
  3546.         free_buf_options(bp_to, TRUE);
  3547.         bp_to->b_p_ro = FALSE;        /* don't copy readonly */
  3548.         bp_to->b_p_tx = bp_from->b_p_tx;
  3549.         bp_to->b_p_ff = vim_strsave(bp_from->b_p_ff);
  3550.         }
  3551.         else
  3552.         free_buf_options(bp_to, FALSE);
  3553.  
  3554.         bp_to->b_p_ai = bp_from->b_p_ai;
  3555.         bp_to->b_p_ai_save = bp_from->b_p_ai_save;
  3556.         bp_to->b_p_sw = bp_from->b_p_sw;
  3557.         bp_to->b_p_tw = bp_from->b_p_tw;
  3558.         bp_to->b_p_tw_save = bp_from->b_p_tw_save;
  3559.         bp_to->b_p_tw_nobin = bp_from->b_p_tw_nobin;
  3560.         bp_to->b_p_wm = bp_from->b_p_wm;
  3561.         bp_to->b_p_wm_save = bp_from->b_p_wm_save;
  3562.         bp_to->b_p_wm_nobin = bp_from->b_p_wm_nobin;
  3563.         bp_to->b_p_bin = bp_from->b_p_bin;
  3564.         bp_to->b_p_et = bp_from->b_p_et;
  3565.         bp_to->b_p_et_nobin = bp_from->b_p_et_nobin;
  3566.         bp_to->b_p_ml = bp_from->b_p_ml;
  3567.         bp_to->b_p_ml_nobin = bp_from->b_p_ml_nobin;
  3568.         bp_to->b_p_inf = bp_from->b_p_inf;
  3569. #ifdef INSERT_EXPAND
  3570.         bp_to->b_p_cpt = vim_strsave(bp_from->b_p_cpt);
  3571. #endif
  3572.         bp_to->b_p_sts = bp_from->b_p_sts;
  3573. #ifndef SHORT_FNAME
  3574.         bp_to->b_p_sn = bp_from->b_p_sn;
  3575. #endif
  3576.         bp_to->b_p_com = vim_strsave(bp_from->b_p_com);
  3577.         bp_to->b_p_fo = vim_strsave(bp_from->b_p_fo);
  3578.         bp_to->b_p_nf = vim_strsave(bp_from->b_p_nf);
  3579. #ifdef SMARTINDENT
  3580.         bp_to->b_p_si = bp_from->b_p_si;
  3581.         bp_to->b_p_si_save = bp_from->b_p_si_save;
  3582. #endif
  3583. #ifdef CINDENT
  3584.         bp_to->b_p_cin = bp_from->b_p_cin;
  3585.         bp_to->b_p_cin_save = bp_from->b_p_cin_save;
  3586.         bp_to->b_p_cink = vim_strsave(bp_from->b_p_cink);
  3587.         bp_to->b_p_cino = vim_strsave(bp_from->b_p_cino);
  3588. #endif
  3589. #if defined(SMARTINDENT) || defined(CINDENT)
  3590.         bp_to->b_p_cinw = vim_strsave(bp_from->b_p_cinw);
  3591. #endif
  3592. #ifdef LISPINDENT
  3593.         bp_to->b_p_lisp = bp_from->b_p_lisp;
  3594.         bp_to->b_p_lisp_save = bp_from->b_p_lisp_save;
  3595. #endif
  3596.  
  3597.         /*
  3598.          * Don't copy the options set by do_help(), use the saved values
  3599.          * Don't touch these at all when BCO_NOHELP is used.
  3600.          */
  3601.         if ((flags & BCO_NOHELP))
  3602.         bp_to->b_p_isk = save_p_isk;
  3603.         else
  3604.         {
  3605.         if (!keep_help_flag && bp_from->b_help && !bp_to->b_help
  3606.                              && help_save_isk != NULL)
  3607.         {
  3608.             bp_to->b_p_isk = vim_strsave(help_save_isk);
  3609.             if (bp_to->b_p_isk != NULL)
  3610.             init_chartab();
  3611.             bp_to->b_p_ts = help_save_ts;
  3612.             bp_to->b_help = FALSE;
  3613.         }
  3614.         else
  3615.         {
  3616.             bp_to->b_p_isk = vim_strsave(bp_from->b_p_isk);
  3617.             vim_memmove(bp_to->b_chartab, bp_from->b_chartab,
  3618.                                  (size_t)256);
  3619.             bp_to->b_p_ts = bp_from->b_p_ts;
  3620.             bp_to->b_help = bp_from->b_help;
  3621.         }
  3622.         }
  3623.     }
  3624.  
  3625.     /*
  3626.      * When the options should be copied (ignoring BCO_ALWAYS), set the
  3627.      * flag that indicates that the options have been initialized.
  3628.      */
  3629.     if (should_copy)
  3630.         bp_to->b_p_initialized = TRUE;
  3631.     }
  3632.  
  3633.     check_buf_options(bp_to);        /* make sure we don't have NULLs */
  3634. }
  3635.  
  3636.  
  3637. static int expand_option_idx = -1;
  3638. static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
  3639.  
  3640.     void
  3641. set_context_in_set_cmd(arg)
  3642.     char_u *arg;
  3643. {
  3644.     int        nextchar;
  3645.     int        flags = 0;    /* init for GCC */
  3646.     int        opt_idx = 0;    /* init for GCC */
  3647.     char_u    *p;
  3648.     char_u    *s;
  3649.     char_u    *after_blank = NULL;
  3650.     int        is_term_option = FALSE;
  3651.     int        key;
  3652.  
  3653.     expand_context = EXPAND_SETTINGS;
  3654.     if (*arg == NUL)
  3655.     {
  3656.     expand_pattern = arg;
  3657.     return;
  3658.     }
  3659.     p = arg + STRLEN(arg) - 1;
  3660.     if (*p == ' ' && *(p - 1) != '\\')
  3661.     {
  3662.     expand_pattern = p + 1;
  3663.     return;
  3664.     }
  3665.     while (p > arg)
  3666.     {
  3667.     s = p;
  3668.     /* count number of backslashes before ' ' or ',' */
  3669.     if (*p == ' ' || *p == ',')
  3670.     {
  3671.         while (s > arg && *(s - 1) == '\\')
  3672.         --s;
  3673.     }
  3674.     /* break at a space with an even number of backslashes */
  3675.     if (*p == ' ' && ((p - s) & 1) == 0)
  3676.     {
  3677.         ++p;
  3678.         break;
  3679.     }
  3680.     /* remember possible start of file name to expand */
  3681.     if (after_blank == NULL
  3682.         && ((*p == ' ' && (p - s) < 2)
  3683.             || (*p == ',' && p == s)))
  3684.         after_blank = p + 1;
  3685.     --p;
  3686.     }
  3687.     if (STRNCMP(p, "no", 2) == 0)
  3688.     {
  3689.     expand_context = EXPAND_BOOL_SETTINGS;
  3690.     p += 2;
  3691.     }
  3692.     if (STRNCMP(p, "inv", 3) == 0)
  3693.     {
  3694.     expand_context = EXPAND_BOOL_SETTINGS;
  3695.     p += 3;
  3696.     }
  3697.     expand_pattern = arg = p;
  3698.     if (*arg == '<')
  3699.     {
  3700.     while (*p != '>')
  3701.         if (*p++ == NUL)        /* expand terminal option name */
  3702.         return;
  3703.     key = get_special_key_code(arg + 1);
  3704.     if (key == 0)            /* unknown name */
  3705.     {
  3706.         expand_context = EXPAND_NOTHING;
  3707.         return;
  3708.     }
  3709.     nextchar = *++p;
  3710.     is_term_option = TRUE;
  3711.     expand_option_name[2] = KEY2TERMCAP0(key);
  3712.     expand_option_name[3] = KEY2TERMCAP1(key);
  3713.     }
  3714.     else
  3715.     {
  3716.     if (p[0] == 't' && p[1] == '_')
  3717.     {
  3718.         p += 2;
  3719.         if (*p != NUL)
  3720.         ++p;
  3721.         if (*p == NUL)
  3722.         return;        /* expand option name */
  3723.         nextchar = *++p;
  3724.         is_term_option = TRUE;
  3725.         expand_option_name[2] = p[-2];
  3726.         expand_option_name[3] = p[-1];
  3727.     }
  3728.     else
  3729.     {
  3730.         while (isalnum(*p) || *p == '_' || *p == '*')   /* Allow * wildcard */
  3731.         p++;
  3732.         if (*p == NUL)
  3733.         return;
  3734.         nextchar = *p;
  3735.         *p = NUL;
  3736.         opt_idx = findoption(arg);
  3737.         *p = nextchar;
  3738.         if (opt_idx == -1 || options[opt_idx].var == NULL)
  3739.         {
  3740.         expand_context = EXPAND_NOTHING;
  3741.         return;
  3742.         }
  3743.         flags = options[opt_idx].flags;
  3744.         if (flags & P_BOOL)
  3745.         {
  3746.         expand_context = EXPAND_NOTHING;
  3747.         return;
  3748.         }
  3749.     }
  3750.     }
  3751.     if ((nextchar != '=' && nextchar != ':')
  3752.                     || expand_context == EXPAND_BOOL_SETTINGS)
  3753.     {
  3754.     expand_context = EXPAND_UNSUCCESSFUL;
  3755.     return;
  3756.     }
  3757.     if (expand_context != EXPAND_BOOL_SETTINGS && p[1] == NUL)
  3758.     {
  3759.     expand_context = EXPAND_OLD_SETTING;
  3760.     if (is_term_option)
  3761.         expand_option_idx = -1;
  3762.     else
  3763.         expand_option_idx = opt_idx;
  3764.     expand_pattern = p + 1;
  3765.     return;
  3766.     }
  3767.     expand_context = EXPAND_NOTHING;
  3768.     if (is_term_option || (flags & P_NUM))
  3769.     return;
  3770.     if (after_blank != NULL)
  3771.     expand_pattern = after_blank;
  3772.     else
  3773.     expand_pattern = p + 1;
  3774.     if (flags & P_EXPAND)
  3775.     {
  3776.     p = options[opt_idx].var;
  3777.     if (p == (char_u *)&p_bdir || p == (char_u *)&p_dir ||
  3778.                                p == (char_u *)&p_path)
  3779.     {
  3780.         expand_context = EXPAND_DIRECTORIES;
  3781.         if (p == (char_u *)&p_path)
  3782.         expand_set_path = TRUE;
  3783.     }
  3784.     else
  3785.         expand_context = EXPAND_FILES;
  3786.     }
  3787.     return;
  3788. }
  3789.  
  3790.     int
  3791. ExpandSettings(prog, num_file, file)
  3792.     vim_regexp    *prog;
  3793.     int        *num_file;
  3794.     char_u    ***file;
  3795. {
  3796.     int num_normal = 0;        /* Number of matching non-term-code settings */
  3797.     int num_term = 0;        /* Number of matching terminal code settings */
  3798.     int opt_idx;
  3799.     int match;
  3800.     int count = 0;
  3801.     char_u *str;
  3802.     int    loop;
  3803.     int is_term_opt;
  3804.     char_u  name_buf[MAX_KEY_NAME_LEN];
  3805.     int    save_reg_ic;
  3806.  
  3807.     /* do this loop twice:
  3808.      * loop == 0: count the number of matching options
  3809.      * loop == 1: copy the matching options into allocated memory
  3810.      */
  3811.     for (loop = 0; loop <= 1; ++loop)
  3812.     {
  3813.     if (expand_context != EXPAND_BOOL_SETTINGS)
  3814.     {
  3815.         if (vim_regexec(prog, (char_u *)"all", TRUE))
  3816.         {
  3817.         if (loop == 0)
  3818.             num_normal++;
  3819.         else
  3820.             (*file)[count++] = vim_strsave((char_u *)"all");
  3821.         }
  3822.         if (vim_regexec(prog, (char_u *)"termcap", TRUE))
  3823.         {
  3824.         if (loop == 0)
  3825.             num_normal++;
  3826.         else
  3827.             (*file)[count++] = vim_strsave((char_u *)"termcap");
  3828.         }
  3829.     }
  3830.     for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
  3831.                                     opt_idx++)
  3832.     {
  3833.         if (options[opt_idx].var == NULL)
  3834.         continue;
  3835.         if (expand_context == EXPAND_BOOL_SETTINGS
  3836.           && !(options[opt_idx].flags & P_BOOL))
  3837.         continue;
  3838.         is_term_opt = istermoption(&options[opt_idx]);
  3839.         if (is_term_opt && num_normal > 0)
  3840.         continue;
  3841.         match = FALSE;
  3842.         if (vim_regexec(prog, str, TRUE) ||
  3843.                     (options[opt_idx].shortname != NULL &&
  3844.              vim_regexec(prog,
  3845.                  (char_u *)options[opt_idx].shortname, TRUE)))
  3846.         match = TRUE;
  3847.         else if (is_term_opt)
  3848.         {
  3849.         name_buf[0] = '<';
  3850.         name_buf[1] = 't';
  3851.         name_buf[2] = '_';
  3852.         name_buf[3] = str[2];
  3853.         name_buf[4] = str[3];
  3854.         name_buf[5] = '>';
  3855.         name_buf[6] = NUL;
  3856.         if (vim_regexec(prog, name_buf, TRUE))
  3857.         {
  3858.             match = TRUE;
  3859.             str = name_buf;
  3860.         }
  3861.         }
  3862.         if (match)
  3863.         {
  3864.         if (loop == 0)
  3865.         {
  3866.             if (is_term_opt)
  3867.             num_term++;
  3868.             else
  3869.             num_normal++;
  3870.         }
  3871.         else
  3872.             (*file)[count++] = vim_strsave(str);
  3873.         }
  3874.     }
  3875.     /*
  3876.      * Check terminal key codes, these are not in the option table
  3877.      */
  3878.     if (expand_context != EXPAND_BOOL_SETTINGS  && num_normal == 0)
  3879.     {
  3880.         for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++)
  3881.         {
  3882.         if (!isprint(str[0]) || !isprint(str[1]))
  3883.             continue;
  3884.  
  3885.         name_buf[0] = 't';
  3886.         name_buf[1] = '_';
  3887.         name_buf[2] = str[0];
  3888.         name_buf[3] = str[1];
  3889.         name_buf[4] = NUL;
  3890.  
  3891.         match = FALSE;
  3892.         if (vim_regexec(prog, name_buf, TRUE))
  3893.             match = TRUE;
  3894.         else
  3895.         {
  3896.             name_buf[0] = '<';
  3897.             name_buf[1] = 't';
  3898.             name_buf[2] = '_';
  3899.             name_buf[3] = str[0];
  3900.             name_buf[4] = str[1];
  3901.             name_buf[5] = '>';
  3902.             name_buf[6] = NUL;
  3903.  
  3904.             if (vim_regexec(prog, name_buf, TRUE))
  3905.             match = TRUE;
  3906.         }
  3907.         if (match)
  3908.         {
  3909.             if (loop == 0)
  3910.             num_term++;
  3911.             else
  3912.             (*file)[count++] = vim_strsave(name_buf);
  3913.         }
  3914.         }
  3915.         /*
  3916.          * Check special key names.
  3917.          */
  3918.         for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++)
  3919.         {
  3920.         name_buf[0] = '<';
  3921.         STRCPY(name_buf + 1, str);
  3922.         STRCAT(name_buf, ">");
  3923.  
  3924.         save_reg_ic = reg_ic;
  3925.         reg_ic = TRUE;            /* ignore case here */
  3926.         if (vim_regexec(prog, name_buf, TRUE))
  3927.         {
  3928.             if (loop == 0)
  3929.             num_term++;
  3930.             else
  3931.             (*file)[count++] = vim_strsave(name_buf);
  3932.         }
  3933.         reg_ic = save_reg_ic;
  3934.         }
  3935.     }
  3936.     if (loop == 0)
  3937.     {
  3938.         if (num_normal > 0)
  3939.         *num_file = num_normal;
  3940.         else if (num_term > 0)
  3941.         *num_file = num_term;
  3942.         else
  3943.         return OK;
  3944.         *file = (char_u **) alloc((unsigned)(*num_file * sizeof(char_u *)));
  3945.         if (*file == NULL)
  3946.         {
  3947.         *file = (char_u **)"";
  3948.         return FAIL;
  3949.         }
  3950.     }
  3951.     }
  3952.     return OK;
  3953. }
  3954.  
  3955.     int
  3956. ExpandOldSetting(num_file, file)
  3957.     int        *num_file;
  3958.     char_u  ***file;
  3959. {
  3960.     char_u  *var = NULL;    /* init for GCC */
  3961.     char_u  *buf;
  3962.  
  3963.     *num_file = 0;
  3964.     *file = (char_u **)alloc((unsigned)sizeof(char_u *));
  3965.     if (*file == NULL)
  3966.     return FAIL;
  3967.  
  3968.     /*
  3969.      * For a terminal key code expand_option_idx is < 0.
  3970.      */
  3971.     if (expand_option_idx < 0)
  3972.     {
  3973.     var = find_termcode(expand_option_name + 2);
  3974.     if (var == NULL)
  3975.         expand_option_idx = findoption(expand_option_name);
  3976.     }
  3977.  
  3978.     if (expand_option_idx >= 0)
  3979.     {
  3980.     /* put string of option value in NameBuff */
  3981.     option_value2string(&options[expand_option_idx]);
  3982.     var = NameBuff;
  3983.     }
  3984.     else if (var == NULL)
  3985.     var = (char_u *)"";
  3986.  
  3987.     /* A backslash is required before some characters */
  3988.     buf = vim_strsave_escaped(var, escape_chars);
  3989.  
  3990.     if (buf == NULL)
  3991.     {
  3992.     vim_free(*file);
  3993.     *file = NULL;
  3994.     return FAIL;
  3995.     }
  3996.  
  3997.     *file[0] = buf;
  3998.     *num_file = 1;
  3999.     return OK;
  4000. }
  4001.  
  4002. /*
  4003.  * Get the value for the numeric or string option *opp in a nice format into
  4004.  * NameBuff[].  Must not be called with a hidden option!
  4005.  */
  4006.     static void
  4007. option_value2string(opp)
  4008.     struct vimoption    *opp;
  4009. {
  4010.     char_u  *varp;
  4011.  
  4012.     varp = get_varp(opp);
  4013.     if (opp->flags & P_NUM)
  4014.     {
  4015.     if ((long *)varp == &p_wc)
  4016.     {
  4017.         if (IS_SPECIAL(p_wc) || find_special_key_in_table((int)p_wc) >= 0)
  4018.         STRCPY(NameBuff, get_special_key_name((int)p_wc, 0));
  4019.         else
  4020.         STRCPY(NameBuff, transchar((int)p_wc));
  4021.     }
  4022.     else
  4023.         sprintf((char *)NameBuff, "%ld", *(long *)varp);
  4024.     }
  4025.     else    /* P_STRING */
  4026.     {
  4027.     varp = *(char_u **)(varp);
  4028.     if (varp == NULL)            /* just in case */
  4029.         NameBuff[0] = NUL;
  4030.     else if (opp->flags & P_EXPAND)
  4031.         home_replace(NULL, varp, NameBuff, MAXPATHL);
  4032.     else
  4033.         STRNCPY(NameBuff, varp, MAXPATHL);
  4034.     }
  4035. }
  4036.  
  4037. #ifdef HAVE_LANGMAP
  4038. /*
  4039.  * Any character has an equivalent character.  This is used for keyboards that
  4040.  * have a special language mode that sends characters above 128 (although
  4041.  * other characters can be translated too).
  4042.  */
  4043.  
  4044. /*
  4045.  * char_u langmap_mapchar[256];
  4046.  * Normally maps each of the 128 upper chars to an <128 ascii char; used to
  4047.  * "translate" native lang chars in normal mode or some cases of
  4048.  * insert mode without having to tediously switch lang mode back&forth.
  4049.  */
  4050.  
  4051.     static void
  4052. langmap_init()
  4053. {
  4054.     int i;
  4055.  
  4056.     for (i = 0; i < 256; i++)        /* we init with a-one-to one map */
  4057.     langmap_mapchar[i] = i;
  4058. }
  4059.  
  4060. /*
  4061.  * Called when langmap option is set; the language map can be
  4062.  * changed at any time!
  4063.  */
  4064.     static void
  4065. langmap_set()
  4066. {
  4067.     char_u  *p;
  4068.     char_u  *p2;
  4069.     int        from, to;
  4070.  
  4071.     langmap_init();                /* back to one-to-one map first */
  4072.  
  4073.     for (p = p_langmap; p[0]; )
  4074.     {
  4075.     for (p2 = p; p2[0] && p2[0] != ',' && p2[0] != ';'; ++p2)
  4076.         if (p2[0] == '\\' && p2[1])
  4077.         ++p2;
  4078.     if (p2[0] == ';')
  4079.         ++p2;        /* abcd;ABCD form, p2 points to A */
  4080.     else
  4081.         p2 = NULL;        /* aAbBcCdD form, p2 is NULL */
  4082.     while (p[0])
  4083.     {
  4084.         if (p[0] == '\\' && p[1])
  4085.         ++p;
  4086.         from = p[0];
  4087.         if (p2 == NULL)
  4088.         {
  4089.         if (p[1] == '\\')
  4090.             ++p;
  4091.         to = p[1];
  4092.         }
  4093.         else
  4094.         {
  4095.         if (p2[0] == '\\')
  4096.             ++p2;
  4097.         to = p2[0];
  4098.         }
  4099.         if (to == NUL)
  4100.         {
  4101.         EMSG2("'langmap': Matching character missing for %s",
  4102.                                  transchar(from));
  4103.         return;
  4104.         }
  4105.         langmap_mapchar[from] = to;
  4106.  
  4107.         /* Advance to next pair */
  4108.         if (p2 == NULL)
  4109.         {
  4110.         p += 2;
  4111.         if (p[0] == ',')
  4112.         {
  4113.             ++p;
  4114.             break;
  4115.         }
  4116.         }
  4117.         else
  4118.         {
  4119.         ++p;
  4120.         ++p2;
  4121.         if (*p == ';')
  4122.         {
  4123.             p = p2;
  4124.             if (p[0])
  4125.             {
  4126.             if (p[0] != ',')
  4127.             {
  4128.                 EMSG2("'langmap': Extra characters after semicolon: %s", p);
  4129.                 return;
  4130.             }
  4131.             ++p;
  4132.             }
  4133.             break;
  4134.         }
  4135.         }
  4136.     }
  4137.     }
  4138. }
  4139. #endif
  4140.  
  4141. /*
  4142.  * Return TRUE if format option 'x' is in effect.
  4143.  * Take care of no formatting when 'paste' is set.
  4144.  */
  4145.     int
  4146. has_format_option(x)
  4147.     int        x;
  4148. {
  4149.     if (p_paste)
  4150.     return FALSE;
  4151.     return (vim_strchr(curbuf->b_p_fo, x) != NULL);
  4152. }
  4153.  
  4154. /*
  4155.  * Return TRUE if "x" is present in 'shortmess' option, or
  4156.  * 'shortmess' contains 'a' and "x" is present in SHM_A.
  4157.  */
  4158.     int
  4159. shortmess(x)
  4160.     int        x;
  4161. {
  4162.     return (   vim_strchr(p_shm, x) != NULL
  4163.         || (vim_strchr(p_shm, 'a') != NULL
  4164.         && vim_strchr((char_u *)SHM_A, x) != NULL));
  4165. }
  4166.  
  4167. /*
  4168.  * set_paste_option() - Called after p_paste was set or reset.
  4169.  */
  4170.     static void
  4171. paste_option_changed()
  4172. {
  4173.     static int        old_p_paste = FALSE;
  4174.     static int        save_sm = 0;
  4175.     static int        save_ru = 0;
  4176. #ifdef RIGHTLEFT
  4177.     static int        save_ri = 0;
  4178.     static int        save_hkmap = 0;
  4179. #endif
  4180.     BUF            *buf;
  4181.  
  4182.     if (p_paste)
  4183.     {
  4184.     /*
  4185.      * Paste switched from off to on.
  4186.      * Save the current values, so they can be restored later.
  4187.      */
  4188.     if (!old_p_paste)
  4189.     {
  4190.         /* save options for each buffer */
  4191.         for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  4192.         {
  4193.         buf->b_p_tw_save = buf->b_p_tw;
  4194.         buf->b_p_wm_save = buf->b_p_wm;
  4195.         buf->b_p_sts_save = buf->b_p_sts;
  4196.         buf->b_p_ai_save = buf->b_p_ai;
  4197. #ifdef SMARTINDENT
  4198.         buf->b_p_si_save = buf->b_p_si;
  4199. #endif
  4200. #ifdef CINDENT
  4201.         buf->b_p_cin_save = buf->b_p_cin;
  4202. #endif
  4203. #ifdef LISPINDENT
  4204.         buf->b_p_lisp_save = buf->b_p_lisp;
  4205. #endif
  4206.         }
  4207.  
  4208.         /* save global options */
  4209.         save_sm = p_sm;
  4210.         save_ru = p_ru;
  4211. #ifdef RIGHTLEFT
  4212.         save_ri = p_ri;
  4213.         save_hkmap = p_hkmap;
  4214. #endif
  4215.     }
  4216.  
  4217.     /*
  4218.      * Always set the option values, also when 'paste' is set when it is
  4219.      * already on.
  4220.      */
  4221.     /* set options for each buffer */
  4222.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  4223.     {
  4224.         buf->b_p_tw = 0;        /* textwidth is 0 */
  4225.         buf->b_p_wm = 0;        /* wrapmargin is 0 */
  4226.         buf->b_p_sts = 0;        /* softtabstop is 0 */
  4227.         buf->b_p_ai = 0;        /* no auto-indent */
  4228. #ifdef SMARTINDENT
  4229.         buf->b_p_si = 0;        /* no smart-indent */
  4230. #endif
  4231. #ifdef CINDENT
  4232.         buf->b_p_cin = 0;        /* no c indenting */
  4233. #endif
  4234. #ifdef LISPINDENT
  4235.         buf->b_p_lisp = 0;        /* no lisp indenting */
  4236. #endif
  4237.     }
  4238.  
  4239.     /* set global options */
  4240.     p_sm = 0;            /* no showmatch */
  4241.     p_ru = 0;            /* no ruler */
  4242. #ifdef RIGHTLEFT
  4243.     p_ri = 0;            /* no reverse insert */
  4244.     p_hkmap = 0;            /* no Hebrew keyboard */
  4245. #endif
  4246.     }
  4247.  
  4248.     /*
  4249.      * Paste switched from on to off: Restore saved values.
  4250.      */
  4251.     else if (old_p_paste)
  4252.     {
  4253.     /* restore options for each buffer */
  4254.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  4255.     {
  4256.         buf->b_p_tw = buf->b_p_tw_save;
  4257.         buf->b_p_wm = buf->b_p_wm_save;
  4258.         buf->b_p_sts = buf->b_p_sts_save;
  4259.         buf->b_p_ai = buf->b_p_ai_save;
  4260. #ifdef SMARTINDENT
  4261.         buf->b_p_si = buf->b_p_si_save;
  4262. #endif
  4263. #ifdef CINDENT
  4264.         buf->b_p_cin = buf->b_p_cin_save;
  4265. #endif
  4266. #ifdef LISPINDENT
  4267.         buf->b_p_lisp = buf->b_p_lisp_save;
  4268. #endif
  4269.     }
  4270.  
  4271.     /* restore global options */
  4272.     p_sm = save_sm;
  4273.     p_ru = save_ru;
  4274. #ifdef RIGHTLEFT
  4275.     p_ri = save_ri;
  4276.     p_hkmap = save_hkmap;
  4277. #endif
  4278.     }
  4279.  
  4280.     old_p_paste = p_paste;
  4281. }
  4282.  
  4283. /*
  4284.  * vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found.
  4285.  *
  4286.  * Reset 'compatible' and set the values for options that didn't get set yet
  4287.  * to the Vim defaults.
  4288.  * Don't do this if the 'compatible' option has been set or reset before.
  4289.  */
  4290.     void
  4291. vimrc_found()
  4292. {
  4293.     int        opt_idx;
  4294.  
  4295.     if (!(options[findoption((char_u *)"cp")].flags & P_WAS_SET))
  4296.     {
  4297.     p_cp = FALSE;
  4298.     for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
  4299.         if (!(options[opt_idx].flags & (P_WAS_SET|P_VI_DEF)))
  4300.         set_option_default(opt_idx, TRUE);
  4301.     init_chartab();            /* make b_p_isk take effect */
  4302.     }
  4303. }
  4304.  
  4305. /*
  4306.  * Set 'compatible' on or off.  Called for "-C" and "-N" command line arg.
  4307.  */
  4308.     void
  4309. change_compatible(on)
  4310.     int        on;
  4311. {
  4312.     if (p_cp != on)
  4313.     {
  4314.     p_cp = on;
  4315.     compatible_set();
  4316.     }
  4317.     options[findoption((char_u *)"cp")].flags |= P_WAS_SET;
  4318. }
  4319.  
  4320. /*
  4321.  * compatible_set() - Called when 'compatible' has been set or unset.
  4322.  *
  4323.  * When 'compatible' set: Set all relevant options (those that have the P_VIM)
  4324.  * flag) to a Vi compatible value.
  4325.  * When 'compatible' is unset: Set all options that have a different default
  4326.  * for Vim (without the P_VI_DEF flag) to that default.
  4327.  */
  4328.     static void
  4329. compatible_set()
  4330. {
  4331.     int        opt_idx;
  4332.  
  4333.     for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
  4334.     if (       ((options[opt_idx].flags & P_VIM) && p_cp)
  4335.         || (!(options[opt_idx].flags & P_VI_DEF) && !p_cp))
  4336.         set_option_default(opt_idx, TRUE);
  4337.     init_chartab();            /* make b_p_isk take effect */
  4338. }
  4339.  
  4340. /*
  4341.  * fill_breakat_flags() -- called when 'breakat' changes value.
  4342.  */
  4343.     static void
  4344. fill_breakat_flags()
  4345. {
  4346.     char_u    *c;
  4347.     int        i;
  4348.  
  4349.     for (i = 0; i < 256; i++)
  4350.     breakat_flags[i] = FALSE;
  4351.  
  4352.     if (p_breakat != NULL)
  4353.     for (c = p_breakat; *c; c++)
  4354.         breakat_flags[*c] = TRUE;
  4355. }
  4356.  
  4357. /*
  4358.  * Check an option that can be a range of string values.
  4359.  *
  4360.  * Return OK for correct value, FAIL otherwise.
  4361.  */
  4362.     static int
  4363. check_opt_strings(val, values, list)
  4364.     char_u  *val;
  4365.     char    **values;
  4366.     int        list;        /* when TRUE: accept a list of values */
  4367. {
  4368.     int        i;
  4369.     int        len;
  4370.  
  4371.     while (*val)
  4372.     {
  4373.     for (i = 0; ; ++i)
  4374.     {
  4375.         if (values[i] == NULL)    /* val not found in values[] */
  4376.         return FAIL;
  4377.  
  4378.         len = STRLEN(values[i]);
  4379.         if (STRNCMP(values[i], val, len) == 0)
  4380.         {
  4381.         if (list && val[len] == ',')
  4382.         {
  4383.             val += len + 1;
  4384.             break;        /* check next item in val list */
  4385.         }
  4386.         else if (val[len] == NUL)
  4387.             return OK;
  4388.         }
  4389.     }
  4390.     }
  4391.     return OK;
  4392. }
  4393.